From 3c4e78e6b755eb33821c4477106f424bd8792d8f Mon Sep 17 00:00:00 2001 From: Matheus Fidelis Date: Tue, 19 Mar 2024 11:32:15 -0300 Subject: [PATCH] feature(geoip2_autoreload): Enable GeoIP2 auto_reload config (#11079) * feature(geoip2_autoreload): GeoIP Autoreload feature(geoip2_autoreload): fix lint feature(geoip2_autoreload): changing flag interval feature(geoip2_autoreload): tests - up and running feature(geoip2_autoreload): tests - up and running feature(geoip2): testing feature(geoip2): remove typo feature(geoip2_autoreload): fixing tests * feature(geoip2_autoreload): working * feature(geoip2_autoreload): including tests on geoip2 test file --- .../nginx-configuration/configmap.md | 7 +++ internal/ingress/controller/config/config.go | 5 ++ rootfs/etc/nginx/template/nginx.tmpl | 24 ++++++++++ test/e2e/settings/geoip2.go | 48 +++++++++++++++++++ 4 files changed, 84 insertions(+) diff --git a/docs/user-guide/nginx-configuration/configmap.md b/docs/user-guide/nginx-configuration/configmap.md index 75971b9a5..ff23196a4 100644 --- a/docs/user-guide/nginx-configuration/configmap.md +++ b/docs/user-guide/nginx-configuration/configmap.md @@ -101,6 +101,7 @@ The following table shows a configuration option's name, type, and the default v |[use-gzip](#use-gzip)|bool|"false"|| |[use-geoip](#use-geoip)|bool|"true"|| |[use-geoip2](#use-geoip2)|bool|"false"|| +|[geoip2-autoreload-in-minutes](#geoip2-autoreload-in-minutes)|int|"0"|| |[enable-brotli](#enable-brotli)|bool|"false"|| |[brotli-level](#brotli-level)|int|4|| |[brotli-min-length](#brotli-min-length)|int|20|| @@ -737,6 +738,12 @@ Alternatively, it is possible to use a volume to mount the files `/etc/nginx/geo _**default:**_ false +## geoip2-autoreload-in-minutes + +Enables the [geoip2 module](https://github.com/leev/ngx_http_geoip2_module) autoreload in MaxMind databases setting the interval in minutes. + +_**default:**_ 0 + ## enable-brotli Enables or disables compression of HTTP responses using the ["brotli" module](https://github.com/google/ngx_brotli). diff --git a/internal/ingress/controller/config/config.go b/internal/ingress/controller/config/config.go index bad82b8b0..12bbb662a 100644 --- a/internal/ingress/controller/config/config.go +++ b/internal/ingress/controller/config/config.go @@ -436,6 +436,10 @@ type Configuration struct { // By default this is disabled UseGeoIP2 bool `json:"use-geoip2,omitempty"` + // GeoIP2AutoReloadMinutes enables autoreload on geoip2 setting the interval in minutes + // By default this is disabled using 0 + GeoIP2AutoReloadMinutes int `json:"geoip2-autoreload-in-minutes,omitempty"` + // Enables or disables the use of the NGINX Brotli Module for compression // https://github.com/google/ngx_brotli EnableBrotli bool `json:"enable-brotli,omitempty"` @@ -841,6 +845,7 @@ func NewDefault() Configuration { EnableAioWrite: true, UseGzip: false, UseGeoIP2: false, + GeoIP2AutoReloadMinutes: 0, WorkerProcesses: strconv.Itoa(runtime.NumCPU()), WorkerShutdownTimeout: "240s", VariablesHashBucketSize: 256, diff --git a/rootfs/etc/nginx/template/nginx.tmpl b/rootfs/etc/nginx/template/nginx.tmpl index d58be2880..d5172ff3f 100644 --- a/rootfs/etc/nginx/template/nginx.tmpl +++ b/rootfs/etc/nginx/template/nginx.tmpl @@ -172,6 +172,9 @@ http { {{ range $index, $file := $all.MaxmindEditionFiles }} {{ if eq $file "GeoLite2-Country.mmdb" }} geoip2 /etc/ingress-controller/geoip/GeoLite2-Country.mmdb { + {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} + auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; + {{ end }} $geoip2_country_code source=$remote_addr country iso_code; $geoip2_country_name source=$remote_addr country names en; $geoip2_country_geoname_id source=$remote_addr country geoname_id; @@ -183,6 +186,9 @@ http { {{ if eq $file "GeoIP2-Country.mmdb" }} geoip2 /etc/ingress-controller/geoip/GeoIP2-Country.mmdb { + {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} + auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; + {{ end }} $geoip2_country_code source=$remote_addr country iso_code; $geoip2_country_name source=$remote_addr country names en; $geoip2_country_geoname_id source=$remote_addr country geoname_id; @@ -194,6 +200,9 @@ http { {{ if eq $file "GeoLite2-City.mmdb" }} geoip2 /etc/ingress-controller/geoip/GeoLite2-City.mmdb { + {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} + auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; + {{ end }} $geoip2_city_country_code source=$remote_addr country iso_code; $geoip2_city_country_name source=$remote_addr country names en; $geoip2_city_country_geoname_id source=$remote_addr country geoname_id; @@ -217,6 +226,9 @@ http { {{ if eq $file "GeoIP2-City.mmdb" }} geoip2 /etc/ingress-controller/geoip/GeoIP2-City.mmdb { + {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} + auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; + {{ end }} $geoip2_city_country_code source=$remote_addr country iso_code; $geoip2_city_country_name source=$remote_addr country names en; $geoip2_city_country_geoname_id source=$remote_addr country geoname_id; @@ -240,6 +252,9 @@ http { {{ if eq $file "GeoLite2-ASN.mmdb" }} geoip2 /etc/ingress-controller/geoip/GeoLite2-ASN.mmdb { + {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} + auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; + {{ end }} $geoip2_asn source=$remote_addr autonomous_system_number; $geoip2_org source=$remote_addr autonomous_system_organization; } @@ -247,6 +262,9 @@ http { {{ if eq $file "GeoIP2-ASN.mmdb" }} geoip2 /etc/ingress-controller/geoip/GeoIP2-ASN.mmdb { + {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} + auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; + {{ end }} $geoip2_asn source=$remote_addr autonomous_system_number; $geoip2_org source=$remote_addr autonomous_system_organization; } @@ -254,6 +272,9 @@ http { {{ if eq $file "GeoIP2-ISP.mmdb" }} geoip2 /etc/ingress-controller/geoip/GeoIP2-ISP.mmdb { + {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} + auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; + {{ end }} $geoip2_isp source=$remote_addr isp; $geoip2_isp_org source=$remote_addr organization; $geoip2_asn source=$remote_addr default=0 autonomous_system_number; @@ -268,6 +289,9 @@ http { {{ if eq $file "GeoIP2-Anonymous-IP.mmdb" }} geoip2 /etc/ingress-controller/geoip/GeoIP2-Anonymous-IP.mmdb { + {{ if (gt $cfg.GeoIP2AutoReloadMinutes 0) }} + auto_reload {{ $cfg.GeoIP2AutoReloadMinutes }}m; + {{ end }} $geoip2_is_anon source=$remote_addr is_anonymous; $geoip2_is_anonymous source=$remote_addr default=0 is_anonymous; $geoip2_is_anonymous_vpn source=$remote_addr default=0 is_anonymous_vpn; diff --git a/test/e2e/settings/geoip2.go b/test/e2e/settings/geoip2.go index 7da26d810..064863734 100644 --- a/test/e2e/settings/geoip2.go +++ b/test/e2e/settings/geoip2.go @@ -124,4 +124,52 @@ var _ = framework.DescribeSetting("Geoip2", func() { Expect(). Status(http.StatusOK) }) + + ginkgo.It("should up and running nginx controller using autoreload flag", func() { + edition := "GeoLite2-Country" + + err := f.UpdateIngressControllerDeployment(func(deployment *appsv1.Deployment) error { + args := deployment.Spec.Template.Spec.Containers[0].Args + args = append(args, "--maxmind-edition-ids="+edition) + deployment.Spec.Template.Spec.Containers[0].Args = args + _, err := f.KubeClientSet.AppsV1().Deployments(f.Namespace).Update(context.TODO(), deployment, metav1.UpdateOptions{}) + return err + }) + assert.Nil(ginkgo.GinkgoT(), err, "updating ingress controller deployment flags") + + filename := fmt.Sprintf("/etc/ingress-controller/geoip/%s.mmdb", edition) + exec, err := f.ExecIngressPod(fmt.Sprintf(`sh -c "mkdir -p '%s' && wget -O '%s' '%s' 2>&1"`, filepath.Dir(filename), filename, testdataURL)) + framework.Logf(exec) + assert.Nil(ginkgo.GinkgoT(), err, fmt.Sprintln("error downloading test geoip2 db", filename)) + + f.SetNginxConfigMapData(map[string]string{ + "use-geoip2": "true", + "geoip2-autoreload-in-minutes": "5", + }) + + // Check Configmap Autoreload Patterns + f.WaitForNginxConfiguration( + func(cfg string) bool { + return strings.Contains(cfg, fmt.Sprintf("geoip2 %s", filename)) && + strings.Contains(cfg, "auto_reload 5m;") + }, + ) + + // Check if Nginx could up, running and routing with auto_reload configs + host := "ping.com" + ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, nil) + f.EnsureIngress(ing) + + f.WaitForNginxServer(host, + func(server string) bool { + return strings.Contains(server, host) && + strings.Contains(server, "location /") + }) + + f.HTTPTestClient(). + GET("/"). + WithHeader("Host", host). + Expect(). + Status(http.StatusOK) + }) })