diff --git a/go.mod b/go.mod index 73c60427b..60f246365 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.22.0 require ( github.com/cenkalti/backoff/v4 v4.3.0 github.com/coreos/go-iptables v0.7.0 - github.com/emirpasic/gods v1.18.1 github.com/kelseyhightower/envconfig v1.4.0 github.com/onsi/ginkgo/v2 v2.20.1 github.com/onsi/gomega v1.34.1 @@ -14,8 +13,8 @@ require ( github.com/pkg/errors v0.9.1 github.com/projectcalico/api v0.0.0-20230602153125-fb7148692637 github.com/prometheus-community/pro-bing v0.4.1 - github.com/prometheus/client_golang v1.19.1 - github.com/submariner-io/admiral v0.19.0-m2.0.20240819074554-489d309b67d9 + github.com/prometheus/client_golang v1.20.2 + github.com/submariner-io/admiral v0.19.0-m2.0.20240830124517-c377f350bf46 github.com/submariner-io/shipyard v0.19.0-m2.0.20240828133900-3d3c2316f606 github.com/vishvananda/netlink v1.3.0 golang.org/x/net v0.28.0 @@ -40,6 +39,7 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emirpasic/gods v1.18.1 // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-logr/logr v1.4.2 // indirect @@ -61,6 +61,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/josharian/native v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect diff --git a/go.sum b/go.sum index 13658be0e..2ed4b1fc1 100644 --- a/go.sum +++ b/go.sum @@ -269,6 +269,8 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -280,6 +282,8 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -376,8 +380,8 @@ github.com/prometheus-community/pro-bing v0.4.1/go.mod h1:aLsw+zqCaDoa2RLVVSX3+U github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_golang v1.20.2 h1:5ctymQzZlyOON1666svgwn3s6IKWgfbjsejTMiXIyjg= +github.com/prometheus/client_golang v1.20.2/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -440,8 +444,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/submariner-io/admiral v0.19.0-m2.0.20240819074554-489d309b67d9 h1:fHQMyLyHCQQl29rW4Plt8Wuq46d2rBK1+cWgGuRf4Dg= -github.com/submariner-io/admiral v0.19.0-m2.0.20240819074554-489d309b67d9/go.mod h1:f4xzFML4SRqETWcyZ32iTy8DH0gLUt2+jrYu6VGXL4Q= +github.com/submariner-io/admiral v0.19.0-m2.0.20240830124517-c377f350bf46 h1:tFoPJtTD13X3xERe6UAJyph3hG00nX8UgdrkMNMu4TM= +github.com/submariner-io/admiral v0.19.0-m2.0.20240830124517-c377f350bf46/go.mod h1:mcqVtEdczVZPmqCzNsRwnPF3uSrqWLKUyQSs79J1MN8= github.com/submariner-io/shipyard v0.19.0-m2.0.20240828133900-3d3c2316f606 h1:0C59+84WEc0n8yuFCL4xNKmDhAZ5o/cGLiIzZy1It/s= github.com/submariner-io/shipyard v0.19.0-m2.0.20240828133900-3d3c2316f606/go.mod h1:Ith3HTqWhsEMmq26xw66OFYlGWO0p9Id86Cw0MIFbqQ= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= diff --git a/pkg/globalnet/controllers/base_controllers.go b/pkg/globalnet/controllers/base_controllers.go index e60edb642..7583538c3 100644 --- a/pkg/globalnet/controllers/base_controllers.go +++ b/pkg/globalnet/controllers/base_controllers.go @@ -27,10 +27,10 @@ import ( "github.com/pkg/errors" "github.com/submariner-io/admiral/pkg/federate" + "github.com/submariner-io/admiral/pkg/ipam" "github.com/submariner-io/admiral/pkg/util" submarinerv1 "github.com/submariner-io/submariner/pkg/apis/submariner.io/v1" pfiface "github.com/submariner-io/submariner/pkg/globalnet/controllers/packetfilter" - "github.com/submariner-io/submariner/pkg/ipam" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/equality" apierrors "k8s.io/apimachinery/pkg/api/errors" diff --git a/pkg/globalnet/controllers/cluster_egressip_controller.go b/pkg/globalnet/controllers/cluster_egressip_controller.go index cfb5eda97..7e436ce34 100644 --- a/pkg/globalnet/controllers/cluster_egressip_controller.go +++ b/pkg/globalnet/controllers/cluster_egressip_controller.go @@ -24,6 +24,7 @@ import ( "github.com/pkg/errors" "github.com/submariner-io/admiral/pkg/federate" + "github.com/submariner-io/admiral/pkg/ipam" "github.com/submariner-io/admiral/pkg/log" "github.com/submariner-io/admiral/pkg/syncer" "github.com/submariner-io/admiral/pkg/util" @@ -31,7 +32,6 @@ import ( "github.com/submariner-io/submariner/pkg/globalnet/constants" "github.com/submariner-io/submariner/pkg/globalnet/controllers/packetfilter" "github.com/submariner-io/submariner/pkg/globalnet/metrics" - "github.com/submariner-io/submariner/pkg/ipam" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" diff --git a/pkg/globalnet/controllers/cluster_egressip_controller_test.go b/pkg/globalnet/controllers/cluster_egressip_controller_test.go index 2b3efac69..5b63a233d 100644 --- a/pkg/globalnet/controllers/cluster_egressip_controller_test.go +++ b/pkg/globalnet/controllers/cluster_egressip_controller_test.go @@ -24,12 +24,13 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/submariner-io/admiral/pkg/ipam" "github.com/submariner-io/admiral/pkg/syncer" "github.com/submariner-io/admiral/pkg/syncer/test" submarinerv1 "github.com/submariner-io/submariner/pkg/apis/submariner.io/v1" "github.com/submariner-io/submariner/pkg/globalnet/constants" "github.com/submariner-io/submariner/pkg/globalnet/controllers" - "github.com/submariner-io/submariner/pkg/ipam" + "github.com/submariner-io/submariner/pkg/globalnet/metrics" "github.com/submariner-io/submariner/pkg/packetfilter" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -365,7 +366,7 @@ func newClusterGlobalEgressIPControllerTestDriver() *clusterGlobalEgressIPContro var err error - t.pool, err = ipam.NewIPPool(t.globalCIDR) + t.pool, err = ipam.NewIPPool(t.globalCIDR, metrics.GlobalnetMetricsReporter) Expect(err).To(Succeed()) }) diff --git a/pkg/globalnet/controllers/controllers_suite_test.go b/pkg/globalnet/controllers/controllers_suite_test.go index 47ae0f349..2b617d360 100644 --- a/pkg/globalnet/controllers/controllers_suite_test.go +++ b/pkg/globalnet/controllers/controllers_suite_test.go @@ -31,6 +31,7 @@ import ( . "github.com/onsi/gomega" "github.com/onsi/gomega/format" fakeDynClient "github.com/submariner-io/admiral/pkg/fake" + "github.com/submariner-io/admiral/pkg/ipam" "github.com/submariner-io/admiral/pkg/log/kzerolog" "github.com/submariner-io/admiral/pkg/resource" "github.com/submariner-io/admiral/pkg/syncer/test" @@ -39,7 +40,6 @@ import ( "github.com/submariner-io/submariner/pkg/cni" "github.com/submariner-io/submariner/pkg/globalnet/constants" "github.com/submariner-io/submariner/pkg/globalnet/controllers" - "github.com/submariner-io/submariner/pkg/ipam" "github.com/submariner-io/submariner/pkg/packetfilter" fakePF "github.com/submariner-io/submariner/pkg/packetfilter/fake" routeAgent "github.com/submariner-io/submariner/pkg/routeagent_driver/constants" diff --git a/pkg/globalnet/controllers/gateway_controller.go b/pkg/globalnet/controllers/gateway_controller.go index 9761d00eb..3bbf8dbf3 100644 --- a/pkg/globalnet/controllers/gateway_controller.go +++ b/pkg/globalnet/controllers/gateway_controller.go @@ -23,12 +23,12 @@ import ( "github.com/pkg/errors" "github.com/submariner-io/admiral/pkg/federate" + "github.com/submariner-io/admiral/pkg/ipam" "github.com/submariner-io/admiral/pkg/syncer" admUtil "github.com/submariner-io/admiral/pkg/util" submarinerv1 "github.com/submariner-io/submariner/pkg/apis/submariner.io/v1" "github.com/submariner-io/submariner/pkg/globalnet/constants" "github.com/submariner-io/submariner/pkg/globalnet/controllers/packetfilter" - "github.com/submariner-io/submariner/pkg/ipam" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" diff --git a/pkg/globalnet/controllers/gateway_controller_test.go b/pkg/globalnet/controllers/gateway_controller_test.go index aab9dc180..a69cd4f7e 100644 --- a/pkg/globalnet/controllers/gateway_controller_test.go +++ b/pkg/globalnet/controllers/gateway_controller_test.go @@ -24,11 +24,12 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/submariner-io/admiral/pkg/ipam" "github.com/submariner-io/admiral/pkg/syncer" submarinerv1 "github.com/submariner-io/submariner/pkg/apis/submariner.io/v1" "github.com/submariner-io/submariner/pkg/globalnet/constants" "github.com/submariner-io/submariner/pkg/globalnet/controllers" - "github.com/submariner-io/submariner/pkg/ipam" + "github.com/submariner-io/submariner/pkg/globalnet/metrics" "github.com/submariner-io/submariner/pkg/packetfilter" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -144,7 +145,7 @@ func newGatewayControllerTestDriver() *gatewayControllerTestDriver { var err error - t.pool, err = ipam.NewIPPool(t.globalCIDR) + t.pool, err = ipam.NewIPPool(t.globalCIDR, metrics.GlobalnetMetricsReporter) Expect(err).To(Succeed()) t.localCIDRs = []string{localCIDR} diff --git a/pkg/globalnet/controllers/gateway_monitor.go b/pkg/globalnet/controllers/gateway_monitor.go index e8028b6f0..88483a373 100644 --- a/pkg/globalnet/controllers/gateway_monitor.go +++ b/pkg/globalnet/controllers/gateway_monitor.go @@ -26,6 +26,7 @@ import ( "github.com/pkg/errors" "github.com/submariner-io/admiral/pkg/federate" + "github.com/submariner-io/admiral/pkg/ipam" "github.com/submariner-io/admiral/pkg/log" "github.com/submariner-io/admiral/pkg/syncer" "github.com/submariner-io/admiral/pkg/syncer/broker" @@ -36,7 +37,7 @@ import ( "github.com/submariner-io/submariner/pkg/event/controller" "github.com/submariner-io/submariner/pkg/globalnet/constants" gnpacketfilter "github.com/submariner-io/submariner/pkg/globalnet/controllers/packetfilter" - "github.com/submariner-io/submariner/pkg/ipam" + "github.com/submariner-io/submariner/pkg/globalnet/metrics" "github.com/submariner-io/submariner/pkg/netlink" "github.com/submariner-io/submariner/pkg/packetfilter" routeAgent "github.com/submariner-io/submariner/pkg/routeagent_driver/constants" @@ -351,7 +352,7 @@ func (g *gatewayMonitor) startControllers() error { return err } - pool, err := ipam.NewIPPool(g.GatewayMonitorConfig.Spec.GlobalCIDR[0]) + pool, err := ipam.NewIPPool(g.GatewayMonitorConfig.Spec.GlobalCIDR[0], metrics.GlobalnetMetricsReporter) if err != nil { return errors.Wrap(err, "error creating the IP pool") } diff --git a/pkg/globalnet/controllers/global_egressip_controller.go b/pkg/globalnet/controllers/global_egressip_controller.go index 285f004dd..9bee0f3b5 100644 --- a/pkg/globalnet/controllers/global_egressip_controller.go +++ b/pkg/globalnet/controllers/global_egressip_controller.go @@ -26,13 +26,13 @@ import ( "github.com/pkg/errors" "github.com/submariner-io/admiral/pkg/federate" + "github.com/submariner-io/admiral/pkg/ipam" "github.com/submariner-io/admiral/pkg/syncer" "github.com/submariner-io/admiral/pkg/util" "github.com/submariner-io/admiral/pkg/watcher" submarinerv1 "github.com/submariner-io/submariner/pkg/apis/submariner.io/v1" "github.com/submariner-io/submariner/pkg/globalnet/controllers/packetfilter" "github.com/submariner-io/submariner/pkg/globalnet/metrics" - "github.com/submariner-io/submariner/pkg/ipam" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/meta" diff --git a/pkg/globalnet/controllers/global_egressip_controller_test.go b/pkg/globalnet/controllers/global_egressip_controller_test.go index cf5e5c2e6..4c1ca044e 100644 --- a/pkg/globalnet/controllers/global_egressip_controller_test.go +++ b/pkg/globalnet/controllers/global_egressip_controller_test.go @@ -25,12 +25,13 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" fakeDynClient "github.com/submariner-io/admiral/pkg/fake" + "github.com/submariner-io/admiral/pkg/ipam" "github.com/submariner-io/admiral/pkg/syncer" "github.com/submariner-io/admiral/pkg/syncer/test" submarinerv1 "github.com/submariner-io/submariner/pkg/apis/submariner.io/v1" "github.com/submariner-io/submariner/pkg/globalnet/constants" "github.com/submariner-io/submariner/pkg/globalnet/controllers" - "github.com/submariner-io/submariner/pkg/ipam" + "github.com/submariner-io/submariner/pkg/globalnet/metrics" "github.com/submariner-io/submariner/pkg/packetfilter" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -597,7 +598,7 @@ func newGlobalEgressIPControllerTestDriver() *globalEgressIPControllerTestDriver var err error - t.pool, err = ipam.NewIPPool(t.globalCIDR) + t.pool, err = ipam.NewIPPool(t.globalCIDR, metrics.GlobalnetMetricsReporter) Expect(err).To(Succeed()) t.watches = fakeDynClient.NewWatchReactor(&t.dynClient.Fake) diff --git a/pkg/globalnet/controllers/global_ingressip_controller.go b/pkg/globalnet/controllers/global_ingressip_controller.go index 05c664565..4cc5fd39e 100644 --- a/pkg/globalnet/controllers/global_ingressip_controller.go +++ b/pkg/globalnet/controllers/global_ingressip_controller.go @@ -25,13 +25,13 @@ import ( "github.com/pkg/errors" "github.com/submariner-io/admiral/pkg/federate" "github.com/submariner-io/admiral/pkg/finalizer" + "github.com/submariner-io/admiral/pkg/ipam" "github.com/submariner-io/admiral/pkg/resource" "github.com/submariner-io/admiral/pkg/syncer" "github.com/submariner-io/admiral/pkg/util" submarinerv1 "github.com/submariner-io/submariner/pkg/apis/submariner.io/v1" pfiface "github.com/submariner-io/submariner/pkg/globalnet/controllers/packetfilter" "github.com/submariner-io/submariner/pkg/globalnet/metrics" - "github.com/submariner-io/submariner/pkg/ipam" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/globalnet/controllers/global_ingressip_controller_test.go b/pkg/globalnet/controllers/global_ingressip_controller_test.go index b6503554f..19ae9cbf2 100644 --- a/pkg/globalnet/controllers/global_ingressip_controller_test.go +++ b/pkg/globalnet/controllers/global_ingressip_controller_test.go @@ -24,11 +24,12 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/submariner-io/admiral/pkg/ipam" "github.com/submariner-io/admiral/pkg/syncer" submarinerv1 "github.com/submariner-io/submariner/pkg/apis/submariner.io/v1" "github.com/submariner-io/submariner/pkg/globalnet/constants" "github.com/submariner-io/submariner/pkg/globalnet/controllers" - "github.com/submariner-io/submariner/pkg/ipam" + "github.com/submariner-io/submariner/pkg/globalnet/metrics" "github.com/submariner-io/submariner/pkg/packetfilter" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -509,7 +510,7 @@ func newGlobalIngressIPControllerDriver() *globalIngressIPControllerTestDriver { var err error - t.pool, err = ipam.NewIPPool(t.globalCIDR) + t.pool, err = ipam.NewIPPool(t.globalCIDR, metrics.GlobalnetMetricsReporter) Expect(err).To(Succeed()) }) diff --git a/pkg/globalnet/controllers/service_export_controller_test.go b/pkg/globalnet/controllers/service_export_controller_test.go index 47cbfdf2e..bfd7b8985 100644 --- a/pkg/globalnet/controllers/service_export_controller_test.go +++ b/pkg/globalnet/controllers/service_export_controller_test.go @@ -24,11 +24,12 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/submariner-io/admiral/pkg/ipam" "github.com/submariner-io/admiral/pkg/syncer" "github.com/submariner-io/admiral/pkg/syncer/test" submarinerv1 "github.com/submariner-io/submariner/pkg/apis/submariner.io/v1" "github.com/submariner-io/submariner/pkg/globalnet/controllers" - "github.com/submariner-io/submariner/pkg/ipam" + "github.com/submariner-io/submariner/pkg/globalnet/metrics" "github.com/submariner-io/submariner/pkg/packetfilter" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -465,7 +466,7 @@ func newServiceExportControllerTestDriver() *serviceExportControllerTestDriver { func (t *serviceExportControllerTestDriver) start() (*syncer.ResourceSyncerConfig, *controllers.IngressPodControllers, syncer.Interface) { var err error - t.pool, err = ipam.NewIPPool(t.globalCIDR) + t.pool, err = ipam.NewIPPool(t.globalCIDR, metrics.GlobalnetMetricsReporter) Expect(err).To(Succeed()) config := &syncer.ResourceSyncerConfig{ diff --git a/pkg/globalnet/controllers/types.go b/pkg/globalnet/controllers/types.go index 2af152dd3..13b94b9b1 100644 --- a/pkg/globalnet/controllers/types.go +++ b/pkg/globalnet/controllers/types.go @@ -24,12 +24,12 @@ import ( "sync/atomic" "time" + "github.com/submariner-io/admiral/pkg/ipam" "github.com/submariner-io/admiral/pkg/log" "github.com/submariner-io/admiral/pkg/syncer" "github.com/submariner-io/admiral/pkg/watcher" "github.com/submariner-io/submariner/pkg/event" pfIface "github.com/submariner-io/submariner/pkg/globalnet/controllers/packetfilter" - "github.com/submariner-io/submariner/pkg/ipam" "github.com/submariner-io/submariner/pkg/packetfilter" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/globalnet/metrics/metrics.go b/pkg/globalnet/metrics/metrics.go index ca597d3b6..c4c5ae7ae 100644 --- a/pkg/globalnet/metrics/metrics.go +++ b/pkg/globalnet/metrics/metrics.go @@ -18,7 +18,10 @@ limitations under the License. package metrics -import "github.com/prometheus/client_golang/prometheus" +import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/submariner-io/admiral/pkg/ipam" +) const ( cidrLabel = "cidr" @@ -72,6 +75,10 @@ var ( ) ) +var GlobalnetMetricsReporter ipam.MetricsReporter = GlobalnetMetrics{} + +type GlobalnetMetrics struct{} + func init() { prometheus.MustRegister(globalIPsAvailabilityGauge, globalIPsAllocatedGauge, globalEgressIPsAllocatedGauge, clusterGlobalEgressIPsAllocatedGauge, globalIngressIPsAllocatedGauge) @@ -116,6 +123,14 @@ func RecordDeallocateGlobalIngressIPs(cidr string, count int) { globalIngressIPsAllocatedGauge.With(prometheus.Labels{cidrLabel: cidr}).Sub(float64(count)) } -func RecordAvailability(cidr string, count int) { +func (r GlobalnetMetrics) RecordAvailability(cidr string, count int) { globalIPsAvailabilityGauge.With(prometheus.Labels{cidrLabel: cidr}).Set(float64(count)) } + +func (r GlobalnetMetrics) RecordIPsAllocated(cidr string, count int) { + RecordAllocateGlobalIPs(cidr, count) +} + +func (r GlobalnetMetrics) RecordIPDeallocated(cidr string) { + RecordDeallocateGlobalIP(cidr) +} diff --git a/pkg/ipam/ipam_suite_test.go b/pkg/ipam/ipam_suite_test.go deleted file mode 100644 index a15a4d77d..000000000 --- a/pkg/ipam/ipam_suite_test.go +++ /dev/null @@ -1,31 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 - -Copyright Contributors to the Submariner project. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package ipam_test - -import ( - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -func TestIPAM(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "IPAM Suite") -} diff --git a/pkg/ipam/ippool.go b/pkg/ipam/ippool.go deleted file mode 100644 index 6fc0fbbdb..000000000 --- a/pkg/ipam/ippool.go +++ /dev/null @@ -1,222 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 - -Copyright Contributors to the Submariner project. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package ipam - -import ( - "encoding/binary" - "fmt" - "math" - "net" - "sync" - - "github.com/emirpasic/gods/maps/treemap" - "github.com/pkg/errors" - "github.com/submariner-io/submariner/pkg/globalnet/metrics" -) - -type IPPool struct { - cidr string - network *net.IPNet - size int - available *treemap.Map // int IP is the key, string IP is the value - mutex sync.RWMutex -} - -func NewIPPool(cidr string) (*IPPool, error) { - _, network, err := net.ParseCIDR(cidr) - if err != nil { - return nil, errors.Wrapf(err, "error parsing CIDR %q", cidr) - } - - ones, totalbits := network.Mask.Size() - - size := int(math.Exp2(float64(totalbits-ones))) - 2 // don't count net and broadcast - if size < 2 { - return nil, fmt.Errorf("invalid prefix for CIDR %q", cidr) - } - - pool := &IPPool{ - cidr: cidr, - network: network, - size: size, - available: treemap.NewWithIntComparator(), - } - - startingIP := ipToInt(pool.network.IP) + 1 - - for i := 0; i < pool.size; i++ { - intIP := startingIP + i - ip := intToIP(intIP).String() - pool.available.Put(intIP, ip) - } - - metrics.RecordAvailability(cidr, size) - - return pool, nil -} - -func ipToInt(ip net.IP) int { - intIP := ip - if len(ip) == 16 { - intIP = ip[12:16] - } - - return int(binary.BigEndian.Uint32(intIP)) -} - -func intToIP(ip int) net.IP { - netIP := make(net.IP, 4) - binary.BigEndian.PutUint32(netIP, uint32(ip)) //nolint:gosec // int -> uint32 conversion won't overflow here - - return netIP -} - -func StringIPToInt(stringIP string) int { - return ipToInt(net.ParseIP(stringIP)) -} - -func (p *IPPool) allocateOne() ([]string, error) { - p.mutex.Lock() - defer p.mutex.Unlock() - - iter := p.available.Iterator() - if iter.Last() { - p.available.Remove(iter.Key()) - metrics.RecordAllocateGlobalIP(p.cidr) - - return []string{iter.Value().(string)}, nil - } - - return nil, errors.New("insufficient IPs available for allocation") -} - -func (p *IPPool) Allocate(num int) ([]string, error) { - switch { - case num < 0: - return nil, errors.New("the number to allocate cannot be negative") - case num == 0: - return []string{}, nil - case num == 1: - return p.allocateOne() - } - - p.mutex.Lock() - defer p.mutex.Unlock() - - if p.available.Size() < num { - return nil, fmt.Errorf("insufficient IPs available (%d) to allocate %d", p.available.Size(), num) - } - - retIPs := make([]string, num) - - var prevIntIP, firstIntIP, current int - - iter := p.available.Iterator() - for iter.Next() { - intIP := iter.Key().(int) - retIPs[current] = iter.Value().(string) - - if current == 0 || prevIntIP+1 != intIP { - firstIntIP = intIP - prevIntIP = intIP - retIPs[0] = retIPs[current] - current = 1 - - continue - } - - prevIntIP = intIP - current++ - - if current == num { - for i := 0; i < num; i++ { - p.available.Remove(firstIntIP) - - firstIntIP++ - } - - metrics.RecordAllocateGlobalIPs(p.cidr, num) - - return retIPs, nil - } - } - - return nil, fmt.Errorf("unable to allocate a contiguous block of %d IPs - available pool size is %d", - num, p.available.Size()) -} - -func (p *IPPool) Release(ips ...string) error { - p.mutex.Lock() - defer p.mutex.Unlock() - - for _, ip := range ips { - if !p.network.Contains(net.ParseIP(ip)) { - return fmt.Errorf("released IP %s is not contained in CIDR %s", ip, p.cidr) - } - - p.available.Put(StringIPToInt(ip), ip) - metrics.RecordDeallocateGlobalIP(p.cidr) - } - - return nil -} - -func (p *IPPool) Reserve(ips ...string) error { - num := len(ips) - if num == 0 { - return nil - } - - intIPs := make([]int, num) - - p.mutex.Lock() - defer p.mutex.Unlock() - - for i := 0; i < num; i++ { - intIPs[i] = StringIPToInt(ips[i]) - - _, found := p.available.Get(intIPs[i]) - if !found { - if !p.network.Contains(net.ParseIP(ips[i])) { - return fmt.Errorf("the requested IP %s is not contained in CIDR %s", ips[i], p.cidr) - } - - return fmt.Errorf("the requested IP %s is already allocated", ips[i]) - } - } - - for i := 0; i < num; i++ { - p.available.Remove(intIPs[i]) - } - - metrics.RecordAllocateGlobalIPs(p.cidr, num) - - return nil -} - -func (p *IPPool) Size() int { - p.mutex.RLock() - defer p.mutex.RUnlock() - - return p.available.Size() -} - -func (p *IPPool) GetCIDR() string { - return p.cidr -} diff --git a/pkg/ipam/ippool_test.go b/pkg/ipam/ippool_test.go deleted file mode 100644 index 52ef498fc..000000000 --- a/pkg/ipam/ippool_test.go +++ /dev/null @@ -1,360 +0,0 @@ -/* -SPDX-License-Identifier: Apache-2.0 - -Copyright Contributors to the Submariner project. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package ipam_test - -import ( - "net" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "github.com/submariner-io/submariner/pkg/ipam" - "k8s.io/utils/set" -) - -const cidrWithSize2 = "169.254.1.0/30" - -var ( - _ = Describe("IP Pool creation", testPoolCreation) - _ = Describe("IP Pool allocation", testPoolAllocation) - _ = Describe("IP Pool release", testPoolRelease) - _ = Describe("IP Pool reserve", testPoolReserve) - _ = Describe("isContiguous", testIsContiguous) -) - -func testPoolCreation() { - When("the CIDR is missing the prefix", func() { - It("should return an error", func() { - pool, err := ipam.NewIPPool("169.254.0.0") - Expect(err).To(HaveOccurred()) - Expect(pool).To(BeNil()) - }) - }) - - When("the CIDR prefix is /33", func() { - It("should return an error", func() { - pool, err := ipam.NewIPPool("169.254.0.0/33") - Expect(err).To(HaveOccurred()) - Expect(pool).To(BeNil()) - }) - }) - - When("the CIDR Prefix is /32", func() { - It("should return an error", func() { - pool, err := ipam.NewIPPool("169.254.1.0/32") - Expect(err).To(HaveOccurred()) - Expect(pool).To(BeNil()) - }) - }) - - When("CIDR Prefix is /31", func() { - It("should return an error", func() { - pool, err := ipam.NewIPPool("169.254.1.0/31") - Expect(err).To(HaveOccurred()) - Expect(pool).To(BeNil()) - }) - }) - - When("CIDR Prefix is /30", func() { - It("should create the pool with size 2", func() { - pool, err := ipam.NewIPPool(cidrWithSize2) - Expect(err).To(Succeed()) - Expect(pool.Size()).Should(Equal(2)) - }) - }) - - When("CIDR Prefix is /24", func() { - It("should create the pool with size 254", func() { - pool, err := ipam.NewIPPool("169.254.1.0/24") - Expect(err).To(Succeed()) - Expect(pool.Size()).Should(Equal(254)) - }) - }) - - When("CIDR Prefix is /16", func() { - It("should create the pool with size 65534", func() { - pool, err := ipam.NewIPPool("169.254.1.0/16") - Expect(err).To(Succeed()) - Expect(pool.Size()).Should(Equal(65534)) - }) - }) -} - -func testPoolAllocation() { - t := newTestDriver() - - When("a single IP is requested", func() { - It("should return an IP contained in the CIDR", func() { - ip := t.allocate(1)[0] - Expect(t.network.Contains(net.ParseIP(ip))).To(BeTrue()) - Expect(t.allocate(1)[0]).ToNot(Equal(ip)) - }) - - Context("and the pool is exhausted", func() { - BeforeEach(func() { - t.cidr = cidrWithSize2 - }) - - It("should return an error", func() { - t.allocate(1) - t.allocate(1) - - _, err := t.pool.Allocate(1) - Expect(err).To(HaveOccurred()) - }) - }) - }) - - When("a block is requested", func() { - It("should return a contiguous list of IPs contained in the CIDR", func() { - ips := t.allocate(10) - verifyContiguous(ips) - - for _, ip := range ips { - Expect(t.network.Contains(net.ParseIP(ip))).To(BeTrue()) - } - }) - - Context("followed by additional requests", func() { - It("should return unique IPs per request", func() { - ips := t.allocate(10) - ips = append(ips, t.allocate(1)...) - - for i := 1; i <= 24; i++ { - n := t.allocate(10) - verifyContiguous(n) - ips = append(ips, n...) - - if 1%10 == 0 { - ips = append(ips, t.allocate(1)...) - } - } - - Expect(set.New(ips...).Len()).To(Equal(len(ips))) - }) - }) - - Context("and the pool is exhausted", func() { - BeforeEach(func() { - t.cidr = cidrWithSize2 - }) - - It("should return an error", func() { - t.allocate(2) - - _, err := t.pool.Allocate(2) - Expect(err).To(HaveOccurred()) - }) - }) - }) - - When("a request is too large for the CIDR", func() { - BeforeEach(func() { - t.cidr = cidrWithSize2 - }) - - It("should return an error", func() { - _, err := t.pool.Allocate(3) - Expect(err).To(HaveOccurred()) - }) - }) - - When("the number requested is zero", func() { - It("should succeed", func() { - t.allocate(0) - }) - }) - - When("the number requested is negative", func() { - It("should return an error", func() { - _, err := t.pool.Allocate(-1) - Expect(err).To(HaveOccurred()) - }) - }) -} - -func testPoolRelease() { - t := newTestDriver() - - When("a single IP is released after allocation", func() { - BeforeEach(func() { - t.cidr = cidrWithSize2 - }) - - It("should be available for re-allocation", func() { - t.allocate(1) - ip := t.allocate(1)[0] - Expect(t.pool.Release(ip)).To(Succeed()) - - ip2 := t.allocate(1)[0] - Expect(ip).To(Equal(ip2)) - }) - }) - - When("an IP block is released after allocation", func() { - It("should be available for re-allocation", func() { - t.allocate(150) - ips := t.allocate(50) - - _, err := t.pool.Allocate(100) - Expect(err).To(HaveOccurred()) - - Expect(t.pool.Release(ips...)).To(Succeed()) - t.allocate(100) - }) - }) - - When("sufficient blocks are released after the pool becomes exhausted", func() { - Context("upon subsequent allocation", func() { - It("should eventually find a sufficient block", func() { - t.allocate(48) - t.allocate(2) - b1 := t.allocate(20) // 70 - t.allocate(15) // 85 - b2 := t.allocate(5) // 90 - b3 := t.allocate(17) // 107 - t.allocate(133) // 240 - - Expect(t.pool.Release(b1...)).To(Succeed()) - _, err := t.pool.Allocate(22) - Expect(err).To(HaveOccurred()) - - Expect(t.pool.Release(b2...)).To(Succeed()) - _, err = t.pool.Allocate(22) - Expect(err).To(HaveOccurred()) - - Expect(t.pool.Release(b3...)).To(Succeed()) - t.allocate(22) - }) - }) - }) - - When("an IP not in the CIDR range is released", func() { - It("should return and error and not return it to the pool", func() { - t.allocate(1) - Expect(t.pool.Release("169.253.1.1")).To(HaveOccurred()) - - ips, err := t.pool.Allocate(t.pool.Size()) - Expect(err).To(Succeed()) - Expect(set.New(ips...).Has("169.253.1.1")).To(BeFalse()) - }) - }) -} - -func testPoolReserve() { - t := newTestDriver() - - When("a block of IPs are available", func() { - It("should reserve them", func() { - err := t.pool.Reserve("169.254.1.1", "169.254.1.2", "169.254.1.3") - Expect(err).To(Succeed()) - - ips := t.allocate(251) - Expect(ips[0]).To(Equal("169.254.1.4")) - verifyContiguous(ips) - }) - }) - - When("an IP isn't available", func() { - It("should return an error", func() { - ips := t.allocate(3) - err := t.pool.Reserve(ips...) - Expect(err).To(HaveOccurred()) - }) - }) - - When("an IP isn't in the CIDR range", func() { - It("should return an error", func() { - err := t.pool.Reserve("169.253.1.1") - Expect(err).To(HaveOccurred()) - }) - }) -} - -func testIsContiguous() { - When("contiguous", func() { - It("should return true", func() { - Expect(isContiguous([]string{"10.20.30.1", "10.20.30.2"})).To(BeTrue()) - Expect(isContiguous([]string{"10.20.30.1", "10.20.30.2", "10.20.30.3"})).To(BeTrue()) - Expect(isContiguous([]string{"1.2.3.255", "1.2.4.0"})).To(BeTrue()) - }) - }) - - When("not contiguous", func() { - It("should return false", func() { - Expect(isContiguous([]string{"10.20.30.1", "10.20.30.3"})).To(BeFalse()) - Expect(isContiguous([]string{"10.20.30.2", "10.20.30.1"})).To(BeFalse()) - Expect(isContiguous([]string{"10.20.30.1", "10.20.30.2", "10.20.30.4"})).To(BeFalse()) - Expect(isContiguous([]string{"10.20.30.1", "10.20.31.2"})).To(BeFalse()) - Expect(isContiguous([]string{"1.2.3.255", "1.2.4.1"})).To(BeFalse()) - }) - }) -} - -func isContiguous(ips []string) bool { - size := len(ips) - for prev, curr := 0, 0; curr < size; prev, curr = curr, curr+1 { - if curr == 0 { - continue - } - - if ipam.StringIPToInt(ips[prev])+1 != ipam.StringIPToInt(ips[curr]) { - return false - } - } - - return true -} - -func verifyContiguous(ips []string) { - Expect(isContiguous(ips)).To(BeTrue(), "IPs are not contiguous: %v", ips) -} - -type testDriver struct { - pool *ipam.IPPool - cidr string - network *net.IPNet -} - -func newTestDriver() *testDriver { - t := &testDriver{} - - BeforeEach(func() { - t.cidr = "169.254.1.0/24" - }) - - JustBeforeEach(func() { - var err error - - _, t.network, err = net.ParseCIDR(t.cidr) - Expect(err).To(Succeed()) - - t.pool, err = ipam.NewIPPool(t.cidr) - Expect(err).To(Succeed()) - }) - - return t -} - -func (t *testDriver) allocate(num int) []string { - ips, err := t.pool.Allocate(num) - Expect(err).To(Succeed()) - Expect(ips).To(HaveLen(num)) - - return ips -}