ingress-nginx-helm/internal/nginx/maxmind.go
Marco Ebert 8d3d4a33bf
Chores: Pick patches from main. (#11103)
* Release version v1.10.0

* set deploy url to v1-10-0 in docs

* quotes around numbers fort ports definitions

* Bump dorny/paths-filter from 3.0.1 to 3.0.2

Bumps [dorny/paths-filter](https://github.com/dorny/paths-filter) from 3.0.1 to 3.0.2.
- [Release notes](https://github.com/dorny/paths-filter/releases)
- [Changelog](https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md)
- [Commits](ebc4d7e9eb...de90cc6fb3)

---
updated-dependencies:
- dependency-name: dorny/paths-filter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

* Bump aquasecurity/trivy-action from 0.17.0 to 0.18.0

Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.17.0 to 0.18.0.
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](84384bd6e7...062f259268)

---
updated-dependencies:
- dependency-name: aquasecurity/trivy-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

* Bump github/codeql-action from 3.24.5 to 3.24.6

Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.24.5 to 3.24.6.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](47b3d888fe...8a470fddaf)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

* Bump github.com/prometheus/common from 0.48.0 to 0.49.0

Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.48.0 to 0.49.0.
- [Release notes](https://github.com/prometheus/common/releases)
- [Commits](https://github.com/prometheus/common/compare/v0.48.0...v0.49.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/common
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

* Bump docker/setup-buildx-action from 3.0.0 to 3.1.0

Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](f95db51fdd...0d103c3126)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

* Bump github.com/stretchr/testify from 1.8.4 to 1.9.0

Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.4 to 1.9.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.8.4...v1.9.0)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

* Bump actions/download-artifact from 4.1.2 to 4.1.4

Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.1.2 to 4.1.4.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](eaceaf801f...c850b930e6)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

* Update README.md

remove older version, left latest for release train.

* docs: update the 404 link to FAQ

* bump golang

* golangci-lint update, ci cleanup, group dependabot updates

* bump golangci-lint to v1.56.x

* cleanup empty lines

* group dependabot updates

* run on job changes as well

* remove deprecated checks

* fix lints and format

* Bump github.com/prometheus/common from 0.49.0 to 0.50.0

Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.49.0 to 0.50.0.
- [Release notes](https://github.com/prometheus/common/releases)
- [Commits](https://github.com/prometheus/common/compare/v0.49.0...v0.50.0)

---
updated-dependencies:
- dependency-name: github.com/prometheus/common
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

* Bump the all group with 1 update

Bumps the all group with 1 update: [google.golang.org/grpc](https://github.com/grpc/grpc-go).

Updates `google.golang.org/grpc` from 1.62.0 to 1.62.1
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.62.0...v1.62.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
...

* Bump the all group with 1 update

Bumps the all group with 1 update: [actions/add-to-project](https://github.com/actions/add-to-project).

Updates `actions/add-to-project` from 0.5.0 to 0.6.0
- [Release notes](https://github.com/actions/add-to-project/releases)
- [Commits](31b3f3ccdc...0609a2702e)

---
updated-dependencies:
- dependency-name: actions/add-to-project
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all
...

* Bump github.com/onsi/ginkgo/v2 from 2.15.0 to 2.16.0

Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.15.0 to 2.16.0.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.15.0...v2.16.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

---------

Co-authored-by: Ricardo Katz <rikatz@users.noreply.github.com>
Co-authored-by: longwuyuan <longwuyuan@gmail.com>
Co-authored-by: Bartosz Fenski <fenio@debian.org>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: James Strong <strong.james.e@gmail.com>
Co-authored-by: Grinish <grinish@gmail.com>
Co-authored-by: Carlos Tadeu Panato Junior <ctadeu@gmail.com>
2024-03-11 14:30:46 -07:00

234 lines
5.6 KiB
Go

/*
Copyright 2020 The Kubernetes Authors.
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 nginx
import (
"archive/tar"
"compress/gzip"
"fmt"
"io"
"net"
"net/http"
"net/url"
"os"
"path"
"strings"
"syscall"
"time"
"k8s.io/apimachinery/pkg/util/wait"
klog "k8s.io/klog/v2"
)
// MaxmindLicenseKey maxmind license key to download databases
var MaxmindLicenseKey = ""
// MaxmindEditionIDs maxmind editions (GeoLite2-City, GeoLite2-Country, GeoIP2-ISP, etc)
var MaxmindEditionIDs = ""
// MaxmindEditionFiles maxmind databases on disk
var MaxmindEditionFiles []string
// MaxmindMirror maxmind database mirror url (http://geoip.local)
var MaxmindMirror = ""
// MaxmindRetriesCount number of attempts to download the GeoIP DB
var MaxmindRetriesCount = 1
// MaxmindRetriesTimeout maxmind download retries timeout in seconds, 0 - do not retry to download if something went wrong
var MaxmindRetriesTimeout = time.Second * 0
// minimumRetriesCount minimum value of the MaxmindRetriesCount parameter. If MaxmindRetriesCount less than minimumRetriesCount, it will be set to minimumRetriesCount
const minimumRetriesCount = 1
const (
geoIPPath = "/etc/ingress-controller/geoip"
dbExtension = ".mmdb"
maxmindURL = "https://download.maxmind.com/app/geoip_download?license_key=%v&edition_id=%v&suffix=tar.gz"
)
// GeoLite2DBExists checks if the required databases for
// the GeoIP2 NGINX module are present in the filesystem
// and indexes the discovered databases for iteration in
// the config.
func GeoLite2DBExists() bool {
files := []string{}
for _, dbName := range strings.Split(MaxmindEditionIDs, ",") {
filename := dbName + dbExtension
if !fileExists(path.Join(geoIPPath, filename)) {
klog.Error(filename, " not found")
return false
}
files = append(files, filename)
}
MaxmindEditionFiles = files
return true
}
// DownloadGeoLite2DB downloads the required databases by the
// GeoIP2 NGINX module using a license key from MaxMind.
func DownloadGeoLite2DB(attempts int, period time.Duration) error {
if attempts < minimumRetriesCount {
attempts = minimumRetriesCount
}
defaultRetry := wait.Backoff{
Steps: attempts,
Duration: period,
Factor: 1.5,
Jitter: 0.1,
}
if period == time.Duration(0) {
defaultRetry.Steps = minimumRetriesCount
}
var lastErr error
retries := 0
lastErr = wait.ExponentialBackoff(defaultRetry, func() (bool, error) {
var dlError error
for _, dbName := range strings.Split(MaxmindEditionIDs, ",") {
dlError = downloadDatabase(dbName)
if dlError != nil {
break
}
}
lastErr = dlError
if dlError == nil {
return true, nil
}
if e, ok := dlError.(*url.Error); ok {
if e, ok := e.Err.(*net.OpError); ok {
if e, ok := e.Err.(*os.SyscallError); ok {
if e.Err == syscall.ECONNREFUSED {
retries++
klog.InfoS("download failed on attempt " + fmt.Sprint(retries))
return false, nil
}
}
}
}
return true, nil
})
return lastErr
}
func createURL(mirror, licenseKey, dbName string) string {
if mirror != "" {
return fmt.Sprintf("%s/%s.tar.gz", mirror, dbName)
}
return fmt.Sprintf(maxmindURL, licenseKey, dbName)
}
func downloadDatabase(dbName string) error {
newURL := createURL(MaxmindMirror, MaxmindLicenseKey, dbName)
req, err := http.NewRequest(http.MethodGet, newURL, http.NoBody)
if err != nil {
return err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("HTTP status %v", resp.Status)
}
archive, err := gzip.NewReader(resp.Body)
if err != nil {
return err
}
defer archive.Close()
mmdbFile := dbName + dbExtension
tarReader := tar.NewReader(archive)
for {
header, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
return err
}
if header.Typeflag == tar.TypeReg {
if !strings.HasSuffix(header.Name, mmdbFile) {
continue
}
return func() error {
outFile, err := os.Create(path.Join(geoIPPath, mmdbFile))
if err != nil {
return err
}
defer outFile.Close()
if _, err := io.CopyN(outFile, tarReader, header.Size); err != nil {
return err
}
return nil
}()
}
}
return fmt.Errorf("the URL %v does not contains the database %v",
fmt.Sprintf(maxmindURL, "XXXXXXX", dbName), mmdbFile)
}
// ValidateGeoLite2DBEditions check provided Maxmind database editions names
func ValidateGeoLite2DBEditions() error {
allowedEditions := map[string]bool{
"GeoIP2-Anonymous-IP": true,
"GeoIP2-Country": true,
"GeoIP2-City": true,
"GeoIP2-Connection-Type": true,
"GeoIP2-Domain": true,
"GeoIP2-ISP": true,
"GeoIP2-ASN": true,
"GeoLite2-ASN": true,
"GeoLite2-Country": true,
"GeoLite2-City": true,
}
for _, edition := range strings.Split(MaxmindEditionIDs, ",") {
if !allowedEditions[edition] {
return fmt.Errorf("unknown Maxmind GeoIP2 edition name: '%s'", edition)
}
}
return nil
}
func _fileExists(filePath string) bool {
info, err := os.Stat(filePath)
if os.IsNotExist(err) {
return false
}
return !info.IsDir()
}
var fileExists = _fileExists