diff --git a/cmds/modules/contd/main.go b/cmds/modules/contd/main.go index 54c7da422..8e6a8cf45 100644 --- a/cmds/modules/contd/main.go +++ b/cmds/modules/contd/main.go @@ -18,7 +18,7 @@ import ( const module = "container" -//Module is contd entry point +// Module is contd entry point var Module cli.Command = cli.Command{ Name: "contd", Usage: "handles containers creations", diff --git a/go.mod b/go.mod index 21cb4fff1..d2374b078 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,6 @@ require ( github.com/joncrlsn/dque v0.0.0-20200702023911-3e80e3146ce5 github.com/lestrrat-go/jwx v1.1.7 github.com/machinebox/graphql v0.2.2 - github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pkg/errors v0.9.1 @@ -97,6 +96,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/holiman/uint256 v1.2.3 // indirect + github.com/jarcoal/httpmock v1.3.1 github.com/josharian/native v0.0.0-20200817173448-b6b71def0850 // indirect github.com/klauspost/compress v1.16.7 // indirect github.com/lestrrat-go/backoff/v2 v2.0.7 // indirect @@ -116,6 +116,7 @@ require ( github.com/moby/sys/mountinfo v0.6.2 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect github.com/nsf/termbox-go v1.1.1 // indirect + github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a github.com/onsi/ginkgo v1.16.4 // indirect github.com/onsi/gomega v1.16.0 // indirect github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 // indirect diff --git a/go.sum b/go.sum index dbc54f94d..4901c22a2 100644 --- a/go.sum +++ b/go.sum @@ -303,6 +303,8 @@ github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZm github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= +github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww= +github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= github.com/jbenet/go-base58 v0.0.0-20150317085156-6237cf65f3a6 h1:4zOlv2my+vf98jT1nQt4bT/yKWUImevYPJ2H344CloE= github.com/jbenet/go-base58 v0.0.0-20150317085156-6237cf65f3a6/go.mod h1:r/8JmuR0qjuCiEhAolkfvdZgmPiHTnJaG0UXCSeR1Zo= github.com/jgautheron/goconst v0.0.0-20170703170152-9740945f5dcb/go.mod h1:82TxjOpWQiPmywlbIaB2ZkqJoSYJdLGPgAJDvM3PbKc= @@ -386,6 +388,8 @@ github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vq github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= +github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43 h1:WgyLFv10Ov49JAQI/ZLUkCZ7VJS3r74hwFIGXJsgZlY= github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43/go.mod h1:+t7E0lkKfbBsebllff1xdTmyJt8lH37niI6kwFk9OTo= github.com/mdlayher/genetlink v1.0.0 h1:OoHN1OdyEIkScEmRgxLEe2M9U8ClMytqA5niynLtfj0= diff --git a/pkg/geoip/README.md b/pkg/geoip/README.md new file mode 100644 index 000000000..58a8781b8 --- /dev/null +++ b/pkg/geoip/README.md @@ -0,0 +1,26 @@ +# Geoip Module + +The `geoip` module provides a simple way to determine the geographical location of the system executing the code. +This includes details such as longitude, latitude, country, city, and continent. + +## Features + +- **Failover Mechanism:** The module attempts to fetch location data from multiple services to ensure high availability. If one URL fails, it logs the error and retries with the next URL. +- **Structured Location Data:** Returns structured data in a `Location` struct for easy integration. + +```go +type Location struct { + Longitude float64 `json:"longitude"` + Latitude float64 `json:"latitude"` + Continent string `json:"continent"` + Country string `json:"country_name"` + CountryCode string `json:"country_code"` + City string `json:"city_name"` +} +``` + +## Usage + +The module provides a single exported function: `Fetch`. + +The `Fetch` function retrieves the geographical location of the system calling the function. diff --git a/pkg/geoip/geoip.go b/pkg/geoip/geoip.go index df108568c..b270b2378 100644 --- a/pkg/geoip/geoip.go +++ b/pkg/geoip/geoip.go @@ -22,14 +22,13 @@ type Location struct { var ( geoipURLs = []string{"https://geoip.grid.tf/", "https://02.geoip.grid.tf/", "https://03.geoip.grid.tf/"} - defaultHttpClient = &http.Client{ + defaultHTTPClient = &http.Client{ Timeout: 10 * time.Second, } ) // Fetch retrieves the location of the system calling this function func Fetch() (Location, error) { - for _, url := range geoipURLs { l, err := getLocation(url) if err != nil { @@ -52,7 +51,7 @@ func getLocation(geoIPService string) (Location, error) { City: "Unknown", } - resp, err := defaultHttpClient.Get(geoIPService) + resp, err := defaultHTTPClient.Get(geoIPService) if err != nil { return l, err } diff --git a/pkg/geoip/geoip_test.go b/pkg/geoip/geoip_test.go new file mode 100644 index 000000000..33a9cdc7a --- /dev/null +++ b/pkg/geoip/geoip_test.go @@ -0,0 +1,70 @@ +package geoip + +import ( + "net/http" + "testing" + + "github.com/jarcoal/httpmock" + "github.com/stretchr/testify/require" +) + +func TestGetLocation(t *testing.T) { + httpmock.Activate() + defer httpmock.DeactivateAndReset() + + require := require.New(t) + + t.Run("test valid response", func(t *testing.T) { + l := Location{ + Continent: "Africa", + Country: "Egypt", + City: "Cairo", + } + + for _, url := range geoipURLs { + httpmock.RegisterResponder("GET", url, + func(req *http.Request) (*http.Response, error) { + return httpmock.NewJsonResponse(200, l) + }, + ) + + resp, err := getLocation(url) + require.NoError(err) + require.Equal(resp, l) + } + }) + + l := Location{ + Continent: "Unknown", + Country: "Unknown", + City: "Unknown", + } + + t.Run("test 404 status code", func(t *testing.T) { + for _, url := range geoipURLs { + httpmock.RegisterResponder("GET", url, + func(req *http.Request) (*http.Response, error) { + return httpmock.NewJsonResponse(404, l) + }, + ) + + resp, err := getLocation(url) + require.Error(err) + require.Equal(resp, l) + } + }) + + t.Run("test invalid response data", func(t *testing.T) { + for _, url := range geoipURLs { + httpmock.RegisterResponder("GET", url, + func(req *http.Request) (*http.Response, error) { + resp, err := httpmock.NewJsonResponse(200, "Cairo") + return resp, err + }, + ) + resp, err := getLocation(url) + require.Error(err) + require.Equal(resp, l) + } + }) +}