diff --git a/.gitignore b/.gitignore index adf8f72..ac671d4 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ # Go workspace file go.work +data.csv +country_geo_locations diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..cb16de7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +FROM golang:1.21-bookworm AS build + +# Create build workspace folder +WORKDIR /workspace +ADD . /workspace + +# Install updates and build tools +RUN apt-get update --yes && \ + apt-get install --yes build-essential + +# Build the actual binary +RUN make build + +# -- -- -- -- -- -- + +# Set up image to run the tool +FROM alpine + +# Create main app folder to run from +WORKDIR /app + +# Copy built binary from build image +COPY --from=build /workspace/country_geo_locations /app + +ENTRYPOINT ["/app/country_geo_locations"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8cb06ab --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +# Build project +.PHONY: build +build: + CGO_ENABLED=0 go build \ + -o country_geo_locations \ + main.go + +# Build project docker container +.PHONY: build/docker +build/docker: + docker build -t registry.neuber.io/country-geo-locations . diff --git a/api/v1/server.go b/api/v1/server.go new file mode 100644 index 0000000..3801b0c --- /dev/null +++ b/api/v1/server.go @@ -0,0 +1,120 @@ +package api_v1 + +import ( + "context" + "net/http" + + "git.ar21.de/tom/country-geo-locations/pkg/geoloc" + "github.com/go-chi/chi/v5" + "github.com/go-chi/render" +) + +func ApiRouter() chi.Router { + r := chi.NewRouter() + + r.Use(render.SetContentType(render.ContentTypeJSON)) + + r.Get("/ping", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("pong")) + }) + + r.Route("/location", func(r chi.Router) { + r.Route("/{ipAddress}", func(r chi.Router) { + r.Use(searchIPCtx) + r.Get("/", searchIP) + }) + }) + + return r +} + +func searchIP(w http.ResponseWriter, r *http.Request) { + ipinfo := r.Context().Value(keyIPInfo).(*geoloc.IPInfo) + + if err := render.Render(w, r, newIPInfoResponse(ipinfo)); err != nil { + render.Render(w, r, errRender(err)) + return + } +} + +func searchIPCtx(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + var ipinfo *geoloc.IPInfo + var ipnetnum uint + var err error + + if ipAddress := chi.URLParam(r, "ipAddress"); ipAddress != "" { + ipnetnum, err = geoloc.GetIPInfo(ipAddress) + if err != nil { + render.Render(w, r, errInvalidRequest(err)) + return + } + for { + ipinfo, err = geoloc.SearchIPNet(ipnetnum) + if err != nil { + render.Render(w, r, errNotFound) + return + } + if ipinfo != nil { + break + } + ipnetnum = ipnetnum - 8 + } + } + ctx := context.WithValue(r.Context(), keyIPInfo, ipinfo) + next.ServeHTTP(w, r.WithContext(ctx)) + }) +} + +type errResponse struct { + Err error `json:"-"` + HTTPStatusCode int `json:"-"` + + StatusText string `json:"status"` + AppCode int64 `json:"code,omitempty"` + ErrorText string `json:"error,omitempty"` +} + +func (e *errResponse) Render(w http.ResponseWriter, r *http.Request) error { + render.Status(r, e.HTTPStatusCode) + return nil +} + +func errInvalidRequest(err error) render.Renderer { + return &errResponse{ + Err: err, + HTTPStatusCode: 400, + StatusText: "Invalid request", + ErrorText: err.Error(), + } +} + +func errRender(err error) render.Renderer { + return &errResponse{ + Err: err, + HTTPStatusCode: 422, + StatusText: "Error rendering response", + ErrorText: err.Error(), + } +} + +var errNotFound = &errResponse{HTTPStatusCode: 404, StatusText: "Resource not found"} + +type key int + +const keyIPInfo key = iota + +type ipInfoResponse struct { + *geoloc.IPInfo + + Elapsed int64 `json:"elapsed"` +} + +func (ir *ipInfoResponse) Render(w http.ResponseWriter, r *http.Request) error { + ir.Elapsed = 10 + return nil +} + +func newIPInfoResponse(ipinfo *geoloc.IPInfo) *ipInfoResponse { + return &ipInfoResponse{IPInfo: ipinfo} +} diff --git a/cfg/cfg.go b/cfg/cfg.go new file mode 100644 index 0000000..238f30a --- /dev/null +++ b/cfg/cfg.go @@ -0,0 +1,59 @@ +package cfg + +import ( + "fmt" + "os" + + "github.com/alecthomas/kong" +) + +type AppSettings struct { + ServerAddress string + DataFile string + DataURL string +} + +var cliStruct struct { + ServerAddress string `name:"listen-address" env:"GEOIP_LISTEN_ADDRESS" help:"Address to use for the metrics server" default:"${default_address}"` + DataFile string `name:"data-file" env:"GEOIP_DATA_FILE" help:"path to data file" default:"${default_file_path}"` + DataURL string `name:"data-url" env:"GEOIP_DATA_URL" help:"url to data file" default:"${default_file_url}"` +} + +func Parse() *AppSettings { + ctx := kong.Parse( + &cliStruct, + kong.Vars{ + "default_address": ":8080", + "default_file_path": "./data.csv", + "default_file_url": "https://data.neuber.io/data.csv", + }, + kong.Name("country_geo_locations"), + kong.Description("🚀 Start a simple web server for GeoIP data"), + kong.UsageOnError(), + ) + + validateFlags(ctx) + settings := &AppSettings{ + ServerAddress: cliStruct.ServerAddress, + DataFile: cliStruct.DataFile, + DataURL: cliStruct.DataURL, + } + return settings +} + +func validateFlags(cliCtx *kong.Context) { + var flagsValid = true + var messages = []string{} + if cliStruct.ServerAddress == "" { + messages = append(messages, "error: invalid server address, must not be blank") + flagsValid = false + } + if !flagsValid { + cliCtx.PrintUsage(false) + fmt.Println() + for i := 0; i < len(messages); i++ { + fmt.Println(messages[i]) + } + os.Exit(1) + } +} diff --git a/go.mod b/go.mod index a01f7bc..35e2e0f 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,21 @@ module git.ar21.de/tom/country-geo-locations go 1.21.5 + +require ( + github.com/alecthomas/kong v0.8.1 + github.com/dustin/go-humanize v1.0.1 + github.com/go-chi/chi/v5 v5.0.10 + github.com/go-chi/render v1.0.3 + github.com/hashicorp/go-memdb v1.3.4 + github.com/levigross/grequests v0.0.0-20231203190023-9c307ef1f48d + github.com/praserx/ipconv v1.2.1 +) + +require ( + github.com/ajg/form v1.5.1 // indirect + github.com/google/go-querystring v1.1.0 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/golang-lru v1.0.2 // indirect + golang.org/x/net v0.19.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..a4898a3 --- /dev/null +++ b/go.sum @@ -0,0 +1,38 @@ +github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/alecthomas/assert/v2 v2.1.0 h1:tbredtNcQnoSd3QBhQWI7QZ3XHOVkw1Moklp2ojoH/0= +github.com/alecthomas/assert/v2 v2.1.0/go.mod h1:b/+1DI2Q6NckYi+3mXyH3wFb8qG37K/DuK80n7WefXA= +github.com/alecthomas/kong v0.8.1 h1:acZdn3m4lLRobeh3Zi2S2EpnXTd1mOL6U7xVml+vfkY= +github.com/alecthomas/kong v0.8.1/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U= +github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE= +github.com/alecthomas/repr v0.1.0/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= +github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4= +github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0= +github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-memdb v1.3.4 h1:XSL3NR682X/cVk2IeV0d70N4DZ9ljI885xAEU8IoK3c= +github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= +github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +github.com/levigross/grequests v0.0.0-20231203190023-9c307ef1f48d h1:8fVmm2qScPn4JAF/YdTtqrPP3n58FgZ4GbKTNfaPuRs= +github.com/levigross/grequests v0.0.0-20231203190023-9c307ef1f48d/go.mod h1:dFu6nuJHC3u9kCDcyGrEL7LwhK2m6Mt+alyiiIjDrRY= +github.com/praserx/ipconv v1.2.1 h1:MWGfrF+OZ0pqIuTlNlMgvJDDbohC3h751oN1+Ov3x4k= +github.com/praserx/ipconv v1.2.1/go.mod h1:DSy+AKre/e3w/npsmUDMio+OR/a2rvmMdI7rerOIgqI= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/main.go b/main.go new file mode 100644 index 0000000..49dd78f --- /dev/null +++ b/main.go @@ -0,0 +1,58 @@ +package main + +import ( + "fmt" + "log" + "net/http" + "os" + "os/signal" + "syscall" + + api_v1 "git.ar21.de/tom/country-geo-locations/api/v1" + "git.ar21.de/tom/country-geo-locations/cfg" + "git.ar21.de/tom/country-geo-locations/pkg/downloader" + "git.ar21.de/tom/country-geo-locations/pkg/geoloc" + "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" + "github.com/go-chi/render" +) + +func main() { + appSettings := cfg.Parse() + handleGracefulShutdown() + if !downloader.FileExists(appSettings.DataFile) { + downloader.DownloadFile(appSettings.DataFile, appSettings.DataURL) + } + + fmt.Printf("Import data from file...\r") + err := geoloc.ImportCSV(appSettings.DataFile) + if err != nil { + fmt.Println("Import data from file failed") + panic(err) + } + fmt.Println("Import data from file successful") + + r := chi.NewRouter() + r.Use(middleware.RequestID) + r.Use(middleware.Logger) + r.Use(middleware.Recoverer) + r.Use(render.SetContentType(render.ContentTypeJSON)) + + r.Mount("/api/v1", api_v1.ApiRouter()) + + log.Printf("starting server at %s\n", appSettings.ServerAddress) + http.ListenAndServe(appSettings.ServerAddress, r) +} + +func handleGracefulShutdown() { + var signals = make(chan os.Signal, 1) + + signal.Notify(signals, syscall.SIGTERM) + signal.Notify(signals, syscall.SIGINT) + + go func() { + sig := <-signals + log.Printf("caught signal: %+v", sig) + os.Exit(0) + }() +} diff --git a/pkg/downloader/downloader.go b/pkg/downloader/downloader.go new file mode 100644 index 0000000..fca33a4 --- /dev/null +++ b/pkg/downloader/downloader.go @@ -0,0 +1,198 @@ +package downloader + +import ( + "crypto/md5" + "crypto/sha1" + "crypto/sha256" + "errors" + "fmt" + "hash" + "io" + "os" + "strings" + "time" + + "github.com/dustin/go-humanize" + req "github.com/levigross/grequests" +) + +var ( + hashes = map[string]hash.Hash{ + "md5": md5.New(), //nolint: gosec + "sha1": sha1.New(), //nolint: gosec + "sha256": sha256.New(), + } +) + +type Context struct { + Filename string + Filesize int64 + Reader io.Reader + Chan chan *Response + Closer []func() error + hashWriter hash.Hash +} + +func NewContext(filename string, filesize int64, hw hash.Hash, closer ...func() error) *Context { + return &Context{ + Filename: filename, + Filesize: filesize, + Chan: make(chan *Response), + Closer: closer, + hashWriter: hw, + } +} + +func (ctx *Context) Checksum() string { + return fmt.Sprintf("%x", ctx.hashWriter.Sum(nil)) +} + +func (ctx *Context) SetReader(rdr io.Reader) { + ctx.Reader = io.TeeReader( + rdr, + io.MultiWriter( + ctx.hashWriter, + &ProgressWriter{ + Filename: ctx.Filename, + Filesize: ctx.Filesize, + Channel: ctx.Chan, + Start: time.Now(), + }, + ), + ) +} + +func (ctx *Context) Close() { + for i := len(ctx.Closer) - 1; i >= 0; i-- { + ctx.Closer[i]() + } +} + +type ProgressWriter struct { + Channel chan *Response + Start time.Time + Filename string + Filesize int64 + Bytes int64 +} + +func (pw *ProgressWriter) Write(data []byte) (int, error) { + pw.Bytes = pw.Bytes + int64(len(data)) + var progress float64 + if pw.Filesize > 0 { + progress = float64(pw.Bytes) / float64(pw.Filesize) * 100 + } + pw.Channel <- &Response{ + Progress: progress, + BytesPerSecond: float64(pw.Bytes) / time.Since(pw.Start).Seconds(), + BytesTransfered: pw.Bytes, + BytesTotal: pw.Filesize, + } + return len(data), nil +} + +type File struct { + URL string + Filename string + Size int64 +} + +type Response struct { + Error error + Progress float64 + BytesPerSecond float64 + BytesTransfered int64 + BytesTotal int64 +} + +func handleError(err error, adds ...string) { + msg := err.Error() + if len(adds) != 0 { + msg = fmt.Sprintf("%s %s", msg, strings.Join(adds, " ")) + } + fmt.Println(msg) + os.Exit(0) +} + +func printProgress(ctx *Context) { + for { + resp, ok := <-ctx.Chan + if !ok { + fmt.Println("\nSaved file to", ctx.Filename) + for key, value := range hashes { + fmt.Printf("%s: %x\n", key, value.Sum(nil)) + } + break + } + if resp.Error != nil { + handleError(resp.Error) + } + if resp.BytesTotal > 0 { + fmt.Printf("\rDownloading %7s/%7s %.02f%%", humanize.Bytes(uint64(resp.BytesTransfered)), humanize.Bytes(uint64(resp.BytesTotal)), resp.Progress) + } else { + fmt.Printf("\rDownloading %7s", humanize.Bytes(uint64(resp.BytesTransfered))) + } + } +} + +func DownloadFile(path, url string) { + file := File{ + URL: url, + Filename: path, + } + response, err := req.Head(file.URL, nil) + if err != nil { + if strings.Contains(err.Error(), "no such host") { + handleError(errors.New("invalid url")) + } else if strings.Contains(err.Error(), "certificate signed by unknown authority") { + handleError(errors.New("certificate signed by unknown authority")) + } + handleError(err) + } + defer response.Close() + if response.StatusCode == 404 { + handleError(errors.New("invalid url")) + } + if response.StatusCode == 401 { + handleError(errors.New("restriced access, credentials required")) + } + response.Close() + + resp, err := req.Get(file.URL, nil) + if err != nil { + handleError(err) + } + + var filesize int64 + if resp.RawResponse.ContentLength != -1 { + filesize = resp.RawResponse.ContentLength + } + ctx := NewContext(file.Filename, filesize, md5.New()) + ctx.SetReader(resp.RawResponse.Body) + + go func(ctx *Context) { + defer ctx.Close() + + dstFile, err := os.Create(ctx.Filename) + if err != nil { + ctx.Chan <- &Response{Error: err} + close(ctx.Chan) + return + } + defer dstFile.Close() + + writer := io.MultiWriter(dstFile, hashes["md5"], hashes["sha1"], hashes["sha256"]) + _, err = io.Copy(writer, ctx.Reader) + if err != nil { + ctx.Chan <- &Response{Error: err} + } + close(ctx.Chan) + }(ctx) + + printProgress(ctx) +} + +func FileExists(path string) bool { + _, err := os.Stat(path) + return !errors.Is(err, os.ErrNotExist) +} diff --git a/pkg/geoloc/csv_import.go b/pkg/geoloc/csv_import.go new file mode 100644 index 0000000..0a1cf53 --- /dev/null +++ b/pkg/geoloc/csv_import.go @@ -0,0 +1,79 @@ +package geoloc + +import ( + "encoding/csv" + "os" + "strconv" +) + +func parseCSV(filePath string) ([]IPInfo, error) { + file, err := os.Open(filePath) + if err != nil { + return nil, err + } + defer file.Close() + + reader := csv.NewReader(file) + + var data []IPInfo + for { + record, err := reader.Read() + if err != nil { + break + } + + ipnumfrom, err := strconv.Atoi(record[0]) + if err != nil { + continue + } + ipnumto, err := strconv.Atoi(record[1]) + if err != nil { + continue + } + if record[2] == "-" { + record[2] = "" + } + if record[3] == "-" { + record[3] = "" + } + if record[4] == "-" { + record[4] = "" + } + if record[5] == "-" { + record[5] = "" + } + latitude, err := strconv.ParseFloat(record[6], 32) + if err != nil { + latitude = 0 + } + longitude, err := strconv.ParseFloat(record[7], 32) + if err != nil { + longitude = 0 + } + + ipinfo := IPInfo{ + IPNumFrom: uint(ipnumfrom), + IPNumTo: uint(ipnumto), + Code: record[2], + Country: record[3], + State: record[4], + City: record[5], + Latitude: float32(latitude), + Longitude: float32(longitude), + } + + data = append(data, ipinfo) + } + + return data, nil +} + +func ImportCSV(filePath string) error { + ipinfos, err := parseCSV(filePath) + if err != nil { + return err + } + + err = CreateDatabase(ipinfos) + return err +} diff --git a/pkg/geoloc/data.go b/pkg/geoloc/data.go deleted file mode 100644 index 9ec8a44..0000000 --- a/pkg/geoloc/data.go +++ /dev/null @@ -1,1969 +0,0 @@ -package geoloc - -type Country struct { - Name string - Code string - Location Location -} - -type Location struct { - Latitude float32 - Longitude float32 -} - -var ( - countries = map[string]Country{ - "AD": { - Name: "Andorra", - Code: "AD", - Location: Location{ - Latitude: 42.55, - Longitude: 1.6, - }, - }, - "AE": { - Name: "United Arab Emirates", - Code: "AE", - Location: Location{ - Latitude: 23.42, - Longitude: 53.85, - }, - }, - "AF": { - Name: "Afghanistan", - Code: "AF", - Location: Location{ - Latitude: 33.94, - Longitude: 67.71, - }, - }, - "AG": { - Name: "Antigua And Barbuda", - Code: "AG", - Location: Location{ - Latitude: 17.06, - Longitude: -61.8, - }, - }, - "AI": { - Name: "Anguilla", - Code: "AI", - Location: Location{ - Latitude: 18.22, - Longitude: -63.07, - }, - }, - "AL": { - Name: "Albania", - Code: "AL", - Location: Location{ - Latitude: 41.15, - Longitude: 20.17, - }, - }, - "AM": { - Name: "Armenia", - Code: "AM", - Location: Location{ - Latitude: 40.07, - Longitude: 45.04, - }, - }, - "AN": { - Name: "Netherlands Antilles", - Code: "AN", - Location: Location{ - Latitude: 12.23, - Longitude: -69.06, - }, - }, - "AO": { - Name: "Angola", - Code: "AO", - Location: Location{ - Latitude: -11.2, - Longitude: 17.87, - }, - }, - "AR": { - Name: "Argentina", - Code: "AR", - Location: Location{ - Latitude: -38.42, - Longitude: -63.62, - }, - }, - "AS": { - Name: "American Samoa", - Code: "AS", - Location: Location{ - Latitude: -14.27, - Longitude: -170.13, - }, - }, - "AT": { - Name: "Austria", - Code: "AT", - Location: Location{ - Latitude: 47.52, - Longitude: 14.55, - }, - }, - "AU": { - Name: "Australia", - Code: "AU", - Location: Location{ - Latitude: -25.27, - Longitude: 133.78, - }, - }, - "AW": { - Name: "Aruba", - Code: "AW", - Location: Location{ - Latitude: 12.52, - Longitude: -69.97, - }, - }, - "AX": { - Name: "Aland Islands", - Code: "AX", - Location: Location{ - Latitude: 60.18, - Longitude: 19.92, - }, - }, - "AZ": { - Name: "Azerbaijan", - Code: "AZ", - Location: Location{ - Latitude: 40.14, - Longitude: 47.58, - }, - }, - "BA": { - Name: "Bosnia And Herzegovina", - Code: "BA", - Location: Location{ - Latitude: 43.92, - Longitude: 17.68, - }, - }, - "BB": { - Name: "Barbados", - Code: "BB", - Location: Location{ - Latitude: 13.19, - Longitude: -59.54, - }, - }, - "BD": { - Name: "Bangladesh", - Code: "BD", - Location: Location{ - Latitude: 23.68, - Longitude: 90.36, - }, - }, - "BE": { - Name: "Belgium", - Code: "BE", - Location: Location{ - Latitude: 50.5, - Longitude: 4.47, - }, - }, - "BF": { - Name: "Burkina Faso", - Code: "BF", - Location: Location{ - Latitude: 12.24, - Longitude: -1.56, - }, - }, - "BG": { - Name: "Bulgaria", - Code: "BG", - Location: Location{ - Latitude: 42.73, - Longitude: 25.49, - }, - }, - "BH": { - Name: "Bahrain", - Code: "BH", - Location: Location{ - Latitude: 25.93, - Longitude: 50.64, - }, - }, - "BI": { - Name: "Burundi", - Code: "BI", - Location: Location{ - Latitude: -3.37, - Longitude: 29.92, - }, - }, - "BJ": { - Name: "Benin", - Code: "BJ", - Location: Location{ - Latitude: 9.31, - Longitude: 2.32, - }, - }, - "BL": { - Name: "Saint Barthelemy", - Code: "BL", - Location: Location{ - Latitude: 17.9, - Longitude: -62.83, - }, - }, - "BM": { - Name: "Bermuda", - Code: "BM", - Location: Location{ - Latitude: 32.32, - Longitude: -64.76, - }, - }, - "BN": { - Name: "Brunei", - Code: "BN", - Location: Location{ - Latitude: 4.54, - Longitude: 114.73, - }, - }, - "BO": { - Name: "Bolivia", - Code: "BO", - Location: Location{ - Latitude: -16.29, - Longitude: -63.59, - }, - }, - "BQ": { - Name: "Bonaire", - Code: "BQ", - Location: Location{ - Latitude: 12.2, - Longitude: -68.26, - }, - }, - "BR": { - Name: "Brazil", - Code: "BR", - Location: Location{ - Latitude: -14.24, - Longitude: -51.39, - }, - }, - "BS": { - Name: "The Bahamas", - Code: "BS", - Location: Location{ - Latitude: 25.03, - Longitude: -77.4, - }, - }, - "BT": { - Name: "Bhutan", - Code: "BT", - Location: Location{ - Latitude: 27.51, - Longitude: 90.43, - }, - }, - "BV": { - Name: "Bouvet Island", - Code: "BV", - Location: Location{ - Latitude: -54.42, - Longitude: 3.41, - }, - }, - "BW": { - Name: "Botswana", - Code: "BW", - Location: Location{ - Latitude: -22.33, - Longitude: 24.68, - }, - }, - "BY": { - Name: "Belarus", - Code: "BY", - Location: Location{ - Latitude: 53.71, - Longitude: 27.95, - }, - }, - "BZ": { - Name: "Belize", - Code: "BZ", - Location: Location{ - Latitude: 17.19, - Longitude: -88.5, - }, - }, - "CA": { - Name: "Canada", - Code: "CA", - Location: Location{ - Latitude: 56.13, - Longitude: -106.35, - }, - }, - "CC": { - Name: "Cocos (Keeling) Islands", - Code: "CC", - Location: Location{ - Latitude: -12.16, - Longitude: 96.87, - }, - }, - "CD": { - Name: "Democratic Republic Of The Congo", - Code: "CD", - Location: Location{ - Latitude: -4.04, - Longitude: 21.76, - }, - }, - "CF": { - Name: "Central African Republic", - Code: "CF", - Location: Location{ - Latitude: 6.61, - Longitude: 20.94, - }, - }, - "CG": { - Name: "Republic Of The Congo", - Code: "CG", - Location: Location{ - Latitude: -0.23, - Longitude: 15.83, - }, - }, - "CH": { - Name: "Switzerland", - Code: "CH", - Location: Location{ - Latitude: 46.82, - Longitude: 8.23, - }, - }, - "CK": { - Name: "Cook Islands", - Code: "CK", - Location: Location{ - Latitude: -21.24, - Longitude: -159.78, - }, - }, - "CL": { - Name: "Chile", - Code: "CL", - Location: Location{ - Latitude: -35.68, - Longitude: 71.54, - }, - }, - "CM": { - Name: "Cameroon", - Code: "CM", - Location: Location{ - Latitude: 7.37, - Longitude: 12.35, - }, - }, - "CN": { - Name: "China", - Code: "CN", - Location: Location{ - Latitude: 35.86, - Longitude: 104.2, - }, - }, - "CO": { - Name: "Colombia", - Code: "CO", - Location: Location{ - Latitude: 4.57, - Longitude: -74.3, - }, - }, - "CR": { - Name: "Costa Rica", - Code: "CR", - Location: Location{ - Latitude: 9.75, - Longitude: -83.75, - }, - }, - "CU": { - Name: "Cuba", - Code: "CU", - Location: Location{ - Latitude: 21.52, - Longitude: -77.78, - }, - }, - "CV": { - Name: "Cape Verde", - Code: "CV", - Location: Location{ - Latitude: 16, - Longitude: -24.01, - }, - }, - "CW": { - Name: "Curacao", - Code: "CW", - Location: Location{ - Latitude: 12.17, - Longitude: -68.99, - }, - }, - "CX": { - Name: "Christmas Island", - Code: "CX", - Location: Location{ - Latitude: -10.45, - Longitude: 105.69, - }, - }, - "CY": { - Name: "Cyprus", - Code: "CY", - Location: Location{ - Latitude: 35.13, - Longitude: 33.43, - }, - }, - "CZ": { - Name: "Czech Republic", - Code: "CZ", - Location: Location{ - Latitude: 49.82, - Longitude: 15.47, - }, - }, - "DE": { - Name: "Germany", - Code: "DE", - Location: Location{ - Latitude: 51.17, - Longitude: 10.45, - }, - }, - "DJ": { - Name: "Djibouti", - Code: "DJ", - Location: Location{ - Latitude: 11.83, - Longitude: 42.59, - }, - }, - "DK": { - Name: "Denmark", - Code: "DK", - Location: Location{ - Latitude: 56.26, - Longitude: 9.5, - }, - }, - "DM": { - Name: "Dominica", - Code: "DM", - Location: Location{ - Latitude: 15.41, - Longitude: -61.37, - }, - }, - "DO": { - Name: "Dominican Republic", - Code: "DO", - Location: Location{ - Latitude: 18.74, - Longitude: -70.16, - }, - }, - "DZ": { - Name: "Algeria", - Code: "DZ", - Location: Location{ - Latitude: 28.03, - Longitude: 1.66, - }, - }, - "EC": { - Name: "Ecuador", - Code: "EC", - Location: Location{ - Latitude: -1.83, - Longitude: -78.18, - }, - }, - "EE": { - Name: "Estonia", - Code: "EE", - Location: Location{ - Latitude: 58.6, - Longitude: 25.01, - }, - }, - "EG": { - Name: "Egypt", - Code: "EG", - Location: Location{ - Latitude: 26.82, - Longitude: 30.8, - }, - }, - "EH": { - Name: "Western Sahara", - Code: "EH", - Location: Location{ - Latitude: 24.22, - Longitude: -12.89, - }, - }, - "ER": { - Name: "Eritrea", - Code: "ER", - Location: Location{ - Latitude: 15.18, - Longitude: 39.78, - }, - }, - "ES": { - Name: "Spain", - Code: "ES", - Location: Location{ - Latitude: 40.46, - Longitude: -3.75, - }, - }, - "ET": { - Name: "Ethiopia", - Code: "ET", - Location: Location{ - Latitude: 9.15, - Longitude: 40.49, - }, - }, - "FI": { - Name: "Finland", - Code: "FI", - Location: Location{ - Latitude: 61.92, - Longitude: 25.75, - }, - }, - "FJ": { - Name: "Fiji", - Code: "FJ", - Location: Location{ - Latitude: -16.58, - Longitude: 179.41, - }, - }, - "FK": { - Name: "Falkland Islands", - Code: "FK", - Location: Location{ - Latitude: -51.8, - Longitude: 59.52, - }, - }, - "FM": { - Name: "Micronesia", - Code: "FM", - Location: Location{ - Latitude: 7.43, - Longitude: 150.55, - }, - }, - "FO": { - Name: "Faroe Islands", - Code: "FO", - Location: Location{ - Latitude: 61.89, - Longitude: -6.91, - }, - }, - "FR": { - Name: "France", - Code: "FR", - Location: Location{ - Latitude: 46.23, - Longitude: 2.21, - }, - }, - "GA": { - Name: "Gabon", - Code: "GA", - Location: Location{ - Latitude: -0.8, - Longitude: 11.61, - }, - }, - "GB": { - Name: "United Kingdom", - Code: "GB", - Location: Location{ - Latitude: 55.38, - Longitude: -3.44, - }, - }, - "GD": { - Name: "Grenada", - Code: "GD", - Location: Location{ - Latitude: 12.26, - Longitude: -61.6, - }, - }, - "GE": { - Name: "Georgia", - Code: "GE", - Location: Location{ - Latitude: 42.32, - Longitude: 43.36, - }, - }, - "GF": { - Name: "French Guiana", - Code: "GF", - Location: Location{ - Latitude: 3.93, - Longitude: -53.13, - }, - }, - "GG": { - Name: "Guernsey", - Code: "GG", - Location: Location{ - Latitude: 49.47, - Longitude: -2.59, - }, - }, - "GH": { - Name: "Ghana", - Code: "GH", - Location: Location{ - Latitude: 7.95, - Longitude: -1.02, - }, - }, - "GI": { - Name: "Gibraltar", - Code: "GI", - Location: Location{ - Latitude: 36.14, - Longitude: -5.35, - }, - }, - "GL": { - Name: "Greenland", - Code: "GL", - Location: Location{ - Latitude: 71.71, - Longitude: 42.6, - }, - }, - "GM": { - Name: "Gambia", - Code: "GM", - Location: Location{ - Latitude: 13.44, - Longitude: -15.31, - }, - }, - "GN": { - Name: "Guinea", - Code: "GN", - Location: Location{ - Latitude: 9.95, - Longitude: -9.7, - }, - }, - "GP": { - Name: "Guadeloupe", - Code: "GP", - Location: Location{ - Latitude: 17, - Longitude: -62.07, - }, - }, - "GQ": { - Name: "Equatorial Guinea", - Code: "GQ", - Location: Location{ - Latitude: 1.65, - Longitude: 10.27, - }, - }, - "GR": { - Name: "Greece", - Code: "GR", - Location: Location{ - Latitude: 39.07, - Longitude: 21.82, - }, - }, - "GS": { - Name: "South Georgia And The South Sandwich Islands", - Code: "GS", - Location: Location{ - Latitude: -54.43, - Longitude: -36.59, - }, - }, - "GT": { - Name: "Guatemala", - Code: "GT", - Location: Location{ - Latitude: 15.78, - Longitude: -90.23, - }, - }, - "GU": { - Name: "Guam", - Code: "GU", - Location: Location{ - Latitude: 13.44, - Longitude: 144.79, - }, - }, - "GW": { - Name: "Guinea-Bissau", - Code: "GW", - Location: Location{ - Latitude: 11.8, - Longitude: -15.18, - }, - }, - "GY": { - Name: "Guyana", - Code: "GY", - Location: Location{ - Latitude: 4.86, - Longitude: -58.93, - }, - }, - "HK": { - Name: "Hong Kong", - Code: "HK", - Location: Location{ - Latitude: 22.4, - Longitude: 114.11, - }, - }, - "HN": { - Name: "Honduras", - Code: "HN", - Location: Location{ - Latitude: 15.2, - Longitude: -86.24, - }, - }, - "HR": { - Name: "Croatia", - Code: "HR", - Location: Location{ - Latitude: 45.1, - Longitude: 15.2, - }, - }, - "HT": { - Name: "Haiti", - Code: "HT", - Location: Location{ - Latitude: 18.97, - Longitude: -72.29, - }, - }, - "HU": { - Name: "Hungary", - Code: "HU", - Location: Location{ - Latitude: 47.16, - Longitude: 19.5, - }, - }, - "ID": { - Name: "Indonesia", - Code: "ID", - Location: Location{ - Latitude: -0.79, - Longitude: 113.92, - }, - }, - "IE": { - Name: "Ireland", - Code: "IE", - Location: Location{ - Latitude: 53.41, - Longitude: -8.24, - }, - }, - "IL": { - Name: "Israel", - Code: "IL", - Location: Location{ - Latitude: 31.05, - Longitude: 34.85, - }, - }, - "IM": { - Name: "Isle Of Man", - Code: "IM", - Location: Location{ - Latitude: 54.24, - Longitude: -4.55, - }, - }, - "IN": { - Name: "India", - Code: "IN", - Location: Location{ - Latitude: 20.59, - Longitude: 78.96, - }, - }, - "IO": { - Name: "British Indian Ocean Territory", - Code: "IO", - Location: Location{ - Latitude: -6.34, - Longitude: 71.88, - }, - }, - "IQ": { - Name: "Iraq", - Code: "IQ", - Location: Location{ - Latitude: 33.22, - Longitude: 43.68, - }, - }, - "IR": { - Name: "Iran", - Code: "IR", - Location: Location{ - Latitude: 32.43, - Longitude: 53.69, - }, - }, - "IS": { - Name: "Iceland", - Code: "IS", - Location: Location{ - Latitude: 64.96, - Longitude: -19.02, - }, - }, - "IT": { - Name: "Italy", - Code: "IT", - Location: Location{ - Latitude: 41.87, - Longitude: 12.57, - }, - }, - "JE": { - Name: "Jersey", - Code: "JE", - Location: Location{ - Latitude: 49.21, - Longitude: -2.13, - }, - }, - "JM": { - Name: "Jamaica", - Code: "JM", - Location: Location{ - Latitude: 18.11, - Longitude: -77.3, - }, - }, - "JO": { - Name: "Jordan", - Code: "JO", - Location: Location{ - Latitude: 30.59, - Longitude: 36.24, - }, - }, - "JP": { - Name: "Japan", - Code: "JP", - Location: Location{ - Latitude: 36.2, - Longitude: 138.25, - }, - }, - "KE": { - Name: "Kenya", - Code: "KE", - Location: Location{ - Latitude: -0.02, - Longitude: 37.91, - }, - }, - "KG": { - Name: "Kyrgyzstan", - Code: "KG", - Location: Location{ - Latitude: 41.2, - Longitude: 74.77, - }, - }, - "KH": { - Name: "Cambodia", - Code: "KH", - Location: Location{ - Latitude: 12.57, - Longitude: 104.99, - }, - }, - "KI": { - Name: "Kiribati", - Code: "KI", - Location: Location{ - Latitude: -3.37, - Longitude: -168.73, - }, - }, - "KM": { - Name: "Comoros", - Code: "KM", - Location: Location{ - Latitude: -11.88, - Longitude: 43.87, - }, - }, - "KN": { - Name: "Saint Kitts And Nevis", - Code: "KN", - Location: Location{ - Latitude: 17.36, - Longitude: -62.78, - }, - }, - "KP": { - Name: "North Korea", - Code: "KP", - Location: Location{ - Latitude: 40.34, - Longitude: 127.51, - }, - }, - "KR": { - Name: "South Korea", - Code: "KR", - Location: Location{ - Latitude: 35.91, - Longitude: 127.77, - }, - }, - "KW": { - Name: "Kuwait", - Code: "KW", - Location: Location{ - Latitude: 29.31, - Longitude: 47.48, - }, - }, - "KY": { - Name: "Cayman Islands", - Code: "KY", - Location: Location{ - Latitude: 19.51, - Longitude: -80.57, - }, - }, - "KZ": { - Name: "Kazakhstan", - Code: "KZ", - Location: Location{ - Latitude: 48.02, - Longitude: 66.92, - }, - }, - "LA": { - Name: "Laos", - Code: "LA", - Location: Location{ - Latitude: 19.86, - Longitude: 102.5, - }, - }, - "LB": { - Name: "Lebanon", - Code: "LB", - Location: Location{ - Latitude: 33.85, - Longitude: 35.86, - }, - }, - "LC": { - Name: "Saint Lucia", - Code: "LC", - Location: Location{ - Latitude: 13.91, - Longitude: -60.98, - }, - }, - "LI": { - Name: "Liechtenstein", - Code: "LI", - Location: Location{ - Latitude: 47.17, - Longitude: 9.56, - }, - }, - "LK": { - Name: "Sri Lanka", - Code: "LK", - Location: Location{ - Latitude: 7.87, - Longitude: 80.77, - }, - }, - "LR": { - Name: "Liberia", - Code: "LR", - Location: Location{ - Latitude: 6.43, - Longitude: -9.43, - }, - }, - "LS": { - Name: "Lesotho", - Code: "LS", - Location: Location{ - Latitude: -29.61, - Longitude: 28.23, - }, - }, - "LT": { - Name: "Lithuania", - Code: "LT", - Location: Location{ - Latitude: 55.17, - Longitude: 23.88, - }, - }, - "LU": { - Name: "Luxembourg", - Code: "LU", - Location: Location{ - Latitude: 49.82, - Longitude: 6.13, - }, - }, - "LV": { - Name: "Latvia", - Code: "LV", - Location: Location{ - Latitude: 56.88, - Longitude: 24.6, - }, - }, - "LY": { - Name: "Libya", - Code: "LY", - Location: Location{ - Latitude: 26.34, - Longitude: 17.23, - }, - }, - "MA": { - Name: "Morocco", - Code: "MA", - Location: Location{ - Latitude: 31.79, - Longitude: -7.09, - }, - }, - "MC": { - Name: "Monaco", - Code: "MC", - Location: Location{ - Latitude: 43.75, - Longitude: 7.41, - }, - }, - "MD": { - Name: "Moldova", - Code: "MD", - Location: Location{ - Latitude: 47.41, - Longitude: 28.37, - }, - }, - "ME": { - Name: "Montenegro", - Code: "ME", - Location: Location{ - Latitude: 42.71, - Longitude: 19.37, - }, - }, - "MF": { - Name: "Saint Martin", - Code: "MF", - Location: Location{ - Latitude: 18.07, - Longitude: -63.05, - }, - }, - "MG": { - Name: "Madagascar", - Code: "MG", - Location: Location{ - Latitude: -18.77, - Longitude: 46.87, - }, - }, - "MH": { - Name: "Marshall Islands", - Code: "MH", - Location: Location{ - Latitude: 7.13, - Longitude: 171.18, - }, - }, - "MK": { - Name: "Macedonia", - Code: "MK", - Location: Location{ - Latitude: 41.61, - Longitude: 21.75, - }, - }, - "ML": { - Name: "Mali", - Code: "ML", - Location: Location{ - Latitude: 17.57, - Longitude: -4, - }, - }, - "MM": { - Name: "Myanmar (Burma)", - Code: "MM", - Location: Location{ - Latitude: 21.91, - Longitude: 95.96, - }, - }, - "MN": { - Name: "Mongolia", - Code: "MN", - Location: Location{ - Latitude: 46.86, - Longitude: 103.85, - }, - }, - "MO": { - Name: "Macau", - Code: "MO", - Location: Location{ - Latitude: 22.2, - Longitude: 113.54, - }, - }, - "MP": { - Name: "Northern Mariana Islands", - Code: "MP", - Location: Location{ - Latitude: 17.33, - Longitude: 145.38, - }, - }, - "MQ": { - Name: "Martinique", - Code: "MQ", - Location: Location{ - Latitude: 14.64, - Longitude: 61.02, - }, - }, - "MR": { - Name: "Mauritania", - Code: "MR", - Location: Location{ - Latitude: 21.01, - Longitude: -10.94, - }, - }, - "MS": { - Name: "Montserrat", - Code: "MS", - Location: Location{ - Latitude: 16.74, - Longitude: -62.19, - }, - }, - "MT": { - Name: "Malta", - Code: "MT", - Location: Location{ - Latitude: 35.94, - Longitude: 14.38, - }, - }, - "MU": { - Name: "Mauritius", - Code: "MU", - Location: Location{ - Latitude: -20.35, - Longitude: 57.55, - }, - }, - "MV": { - Name: "Maldives", - Code: "MV", - Location: Location{ - Latitude: 3.2, - Longitude: 73.22, - }, - }, - "MW": { - Name: "Malawi", - Code: "MW", - Location: Location{ - Latitude: -13.25, - Longitude: 34.3, - }, - }, - "MX": { - Name: "Mexico", - Code: "MX", - Location: Location{ - Latitude: 23.63, - Longitude: -102.55, - }, - }, - "MY": { - Name: "Malaysia", - Code: "MY", - Location: Location{ - Latitude: 4.21, - Longitude: 101.98, - }, - }, - "MZ": { - Name: "Mozambique", - Code: "MZ", - Location: Location{ - Latitude: -18.67, - Longitude: 35.53, - }, - }, - "NA": { - Name: "Namibia", - Code: "NA", - Location: Location{ - Latitude: -22.96, - Longitude: 18.49, - }, - }, - "NC": { - Name: "New Caledonia", - Code: "NC", - Location: Location{ - Latitude: -20.9, - Longitude: 165.62, - }, - }, - "NE": { - Name: "Niger", - Code: "NE", - Location: Location{ - Latitude: 17.61, - Longitude: 8.08, - }, - }, - "NF": { - Name: "Norfolk Island", - Code: "NF", - Location: Location{ - Latitude: -29.04, - Longitude: 167.95, - }, - }, - "NG": { - Name: "Nigeria", - Code: "NG", - Location: Location{ - Latitude: 9.08, - Longitude: 8.68, - }, - }, - "NI": { - Name: "Nicaragua", - Code: "NI", - Location: Location{ - Latitude: 12.87, - Longitude: -85.21, - }, - }, - "NL": { - Name: "Netherlands", - Code: "NL", - Location: Location{ - Latitude: 52.13, - Longitude: 5.29, - }, - }, - "NO": { - Name: "Norway", - Code: "NO", - Location: Location{ - Latitude: 60.47, - Longitude: 8.47, - }, - }, - "NP": { - Name: "Nepal", - Code: "NP", - Location: Location{ - Latitude: 28.39, - Longitude: 84.12, - }, - }, - "NR": { - Name: "Nauru", - Code: "NR", - Location: Location{ - Latitude: -0.52, - Longitude: 166.93, - }, - }, - "NU": { - Name: "Niue", - Code: "NU", - Location: Location{ - Latitude: -19.05, - Longitude: -169.87, - }, - }, - "NZ": { - Name: "New Zealand", - Code: "NZ", - Location: Location{ - Latitude: -40.9, - Longitude: 174.89, - }, - }, - "OM": { - Name: "Oman", - Code: "OM", - Location: Location{ - Latitude: 21.51, - Longitude: 55.92, - }, - }, - "PA": { - Name: "Panama", - Code: "PA", - Location: Location{ - Latitude: 8.54, - Longitude: -80.78, - }, - }, - "PE": { - Name: "Peru", - Code: "PE", - Location: Location{ - Latitude: -9.19, - Longitude: -75.02, - }, - }, - "PF": { - Name: "French Polynesia", - Code: "PF", - Location: Location{ - Latitude: -17.68, - Longitude: -149.41, - }, - }, - "PG": { - Name: "Papua New Guinea", - Code: "PG", - Location: Location{ - Latitude: -6.31, - Longitude: 143.96, - }, - }, - "PH": { - Name: "Philippines", - Code: "PH", - Location: Location{ - Latitude: 12.88, - Longitude: 121.77, - }, - }, - "PK": { - Name: "Pakistan", - Code: "PK", - Location: Location{ - Latitude: 30.38, - Longitude: 69.35, - }, - }, - "PL": { - Name: "Poland", - Code: "PL", - Location: Location{ - Latitude: 51.92, - Longitude: 19.15, - }, - }, - "PM": { - Name: "Saint Pierre And Miquelon", - Code: "PM", - Location: Location{ - Latitude: 46.94, - Longitude: -56.27, - }, - }, - "PN": { - Name: "Pitcairn Islands", - Code: "PN", - Location: Location{ - Latitude: -24.7, - Longitude: -127.44, - }, - }, - "PR": { - Name: "Puerto Rico", - Code: "PR", - Location: Location{ - Latitude: 18.22, - Longitude: -66.59, - }, - }, - "PT": { - Name: "Portugal", - Code: "PT", - Location: Location{ - Latitude: 39.4, - Longitude: -8.22, - }, - }, - "PW": { - Name: "Palau", - Code: "PW", - Location: Location{ - Latitude: 7.51, - Longitude: 134.58, - }, - }, - "PY": { - Name: "Paraguay", - Code: "PY", - Location: Location{ - Latitude: -23.44, - Longitude: -58.44, - }, - }, - "QA": { - Name: "Qatar", - Code: "QA", - Location: Location{ - Latitude: 25.35, - Longitude: 51.18, - }, - }, - "RE": { - Name: "Reunion", - Code: "RE", - Location: Location{ - Latitude: -21.12, - Longitude: 55.54, - }, - }, - "RO": { - Name: "Romania", - Code: "RO", - Location: Location{ - Latitude: 45.94, - Longitude: 24.97, - }, - }, - "RS": { - Name: "Serbia", - Code: "RS", - Location: Location{ - Latitude: 44.02, - Longitude: 21.01, - }, - }, - "RU": { - Name: "Russia", - Code: "RU", - Location: Location{ - Latitude: 61.52, - Longitude: 105.32, - }, - }, - "RW": { - Name: "Rwanda", - Code: "RW", - Location: Location{ - Latitude: -1.94, - Longitude: 29.87, - }, - }, - "SA": { - Name: "Saudi Arabia", - Code: "SA", - Location: Location{ - Latitude: 23.89, - Longitude: 45.08, - }, - }, - "SB": { - Name: "Solomon Islands", - Code: "SB", - Location: Location{ - Latitude: -9.65, - Longitude: 160.16, - }, - }, - "SC": { - Name: "Seychelles", - Code: "SC", - Location: Location{ - Latitude: -4.68, - Longitude: 55.49, - }, - }, - "SD": { - Name: "Sudan", - Code: "SD", - Location: Location{ - Latitude: 12.86, - Longitude: 30.22, - }, - }, - "SE": { - Name: "Sweden", - Code: "SE", - Location: Location{ - Latitude: 60.13, - Longitude: 18.64, - }, - }, - "SG": { - Name: "Singapore", - Code: "SG", - Location: Location{ - Latitude: 1.35, - Longitude: 103.82, - }, - }, - "SH": { - Name: "Saint Helena", - Code: "SH", - Location: Location{ - Latitude: -24.14, - Longitude: -10.03, - }, - }, - "SI": { - Name: "Slovenia", - Code: "SI", - Location: Location{ - Latitude: 46.15, - Longitude: 15, - }, - }, - "SJ": { - Name: "Svalbard And Jan Mayen", - Code: "SJ", - Location: Location{ - Latitude: 77.55, - Longitude: 23.67, - }, - }, - "SK": { - Name: "Slovakia", - Code: "SK", - Location: Location{ - Latitude: 48.67, - Longitude: 19.7, - }, - }, - "SL": { - Name: "Sierra Leone", - Code: "SL", - Location: Location{ - Latitude: 8.46, - Longitude: -11.78, - }, - }, - "SM": { - Name: "San Marino", - Code: "SM", - Location: Location{ - Latitude: 43.94, - Longitude: 12.46, - }, - }, - "SN": { - Name: "Senegal", - Code: "SN", - Location: Location{ - Latitude: 14.5, - Longitude: -14.45, - }, - }, - "SO": { - Name: "Somalia", - Code: "SO", - Location: Location{ - Latitude: 5.15, - Longitude: 46.2, - }, - }, - "SR": { - Name: "SuriName", - Code: "SR", - Location: Location{ - Latitude: 3.92, - Longitude: -56.03, - }, - }, - "ST": { - Name: "Sao Tome And Principe", - Code: "ST", - Location: Location{ - Latitude: 0.19, - Longitude: 6.61, - }, - }, - "SV": { - Name: "El Salvador", - Code: "SV", - Location: Location{ - Latitude: 13.79, - Longitude: -88.9, - }, - }, - "SX": { - Name: "Sint Maarten", - Code: "SX", - Location: Location{ - Latitude: 18.03, - Longitude: -63.05, - }, - }, - "SY": { - Name: "Syria", - Code: "SY", - Location: Location{ - Latitude: 34.8, - Longitude: 39, - }, - }, - "SZ": { - Name: "Swaziland", - Code: "SZ", - Location: Location{ - Latitude: -26.52, - Longitude: 31.47, - }, - }, - "TC": { - Name: "Turks And Caicos Islands", - Code: "TC", - Location: Location{ - Latitude: 21.69, - Longitude: -71.8, - }, - }, - "TD": { - Name: "Chad", - Code: "TD", - Location: Location{ - Latitude: 15.45, - Longitude: 18.73, - }, - }, - "TG": { - Name: "Togo", - Code: "TG", - Location: Location{ - Latitude: 8.62, - Longitude: 0.82, - }, - }, - "TH": { - Name: "Thailand", - Code: "TH", - Location: Location{ - Latitude: 15.87, - Longitude: 100.99, - }, - }, - "TJ": { - Name: "Tajikistan", - Code: "TJ", - Location: Location{ - Latitude: 38.86, - Longitude: 71.28, - }, - }, - "TK": { - Name: "Tokelau", - Code: "TK", - Location: Location{ - Latitude: -8.97, - Longitude: -171.86, - }, - }, - "TL": { - Name: "Timor-Leste", - Code: "TL", - Location: Location{ - Latitude: -8.87, - Longitude: 125.73, - }, - }, - "TM": { - Name: "Turkmenistan", - Code: "TM", - Location: Location{ - Latitude: 38.97, - Longitude: 59.56, - }, - }, - "TN": { - Name: "Tunisia", - Code: "TN", - Location: Location{ - Latitude: 33.89, - Longitude: 9.54, - }, - }, - "TO": { - Name: "Tonga", - Code: "TO", - Location: Location{ - Latitude: -21.18, - Longitude: -175.2, - }, - }, - "TR": { - Name: "Turkey", - Code: "TR", - Location: Location{ - Latitude: 38.96, - Longitude: 35.24, - }, - }, - "TT": { - Name: "Trinidad And Tobago", - Code: "TT", - Location: Location{ - Latitude: 10.69, - Longitude: -61.22, - }, - }, - "TV": { - Name: "Tuvalu", - Code: "TV", - Location: Location{ - Latitude: -7.11, - Longitude: 177.65, - }, - }, - "TW": { - Name: "Taiwan", - Code: "TW", - Location: Location{ - Latitude: 23.7, - Longitude: 120.96, - }, - }, - "TZ": { - Name: "Tanzania", - Code: "TZ", - Location: Location{ - Latitude: -6.37, - Longitude: 34.89, - }, - }, - "UA": { - Name: "Ukraine", - Code: "UA", - Location: Location{ - Latitude: 48.38, - Longitude: 31.17, - }, - }, - "UG": { - Name: "Uganda", - Code: "UG", - Location: Location{ - Latitude: 1.37, - Longitude: 32.29, - }, - }, - "US": { - Name: "United States Of America", - Code: "US", - Location: Location{ - Latitude: 37.09, - Longitude: -95.71, - }, - }, - "UY": { - Name: "Uruguay", - Code: "UY", - Location: Location{ - Latitude: -32.52, - Longitude: -55.77, - }, - }, - "UZ": { - Name: "Uzbekistan", - Code: "UZ", - Location: Location{ - Latitude: 41.38, - Longitude: 64.59, - }, - }, - "VA": { - Name: "Vatican City", - Code: "VA", - Location: Location{ - Latitude: 41.9, - Longitude: 12.45, - }, - }, - "VC": { - Name: "Saint Vincent And The Grenadines", - Code: "VC", - Location: Location{ - Latitude: 12.98, - Longitude: -61.29, - }, - }, - "VE": { - Name: "Venezuela", - Code: "VE", - Location: Location{ - Latitude: 6.42, - Longitude: -66.59, - }, - }, - "VG": { - Name: "British Virgin Islands", - Code: "VG", - Location: Location{ - Latitude: 18.42, - Longitude: -64.64, - }, - }, - "VI": { - Name: "US Virgin Islands", - Code: "VI", - Location: Location{ - Latitude: 18.34, - Longitude: -64.9, - }, - }, - "VN": { - Name: "Vietnam", - Code: "VN", - Location: Location{ - Latitude: 14.06, - Longitude: 108.28, - }, - }, - "VU": { - Name: "Vanuatu", - Code: "VU", - Location: Location{ - Latitude: -15.38, - Longitude: 166.96, - }, - }, - "WF": { - Name: "Wallis And Futuna", - Code: "WF", - Location: Location{ - Latitude: -13.77, - Longitude: -177.16, - }, - }, - "WS": { - Name: "Samoa", - Code: "WS", - Location: Location{ - Latitude: -13.76, - Longitude: -172.1, - }, - }, - "XK": { - Name: "Kosovo", - Code: "XK", - Location: Location{ - Latitude: 42.6, - Longitude: 20.9, - }, - }, - "YE": { - Name: "Yemen", - Code: "YE", - Location: Location{ - Latitude: 15.55, - Longitude: 48.52, - }, - }, - "YT": { - Name: "Mayotte", - Code: "YT", - Location: Location{ - Latitude: -12.83, - Longitude: 45.17, - }, - }, - "ZA": { - Name: "South Africa", - Code: "ZA", - Location: Location{ - Latitude: -30.56, - Longitude: 22.94, - }, - }, - "ZM": { - Name: "Zambia", - Code: "ZM", - Location: Location{ - Latitude: -13.13, - Longitude: 27.85, - }, - }, - "ZW": { - Name: "Zimbabwe", - Code: "ZW", - Location: Location{ - Latitude: -19.02, - Longitude: 29.15, - }, - }, - } -) diff --git a/pkg/geoloc/database.go b/pkg/geoloc/database.go new file mode 100644 index 0000000..a1c839d --- /dev/null +++ b/pkg/geoloc/database.go @@ -0,0 +1,75 @@ +package geoloc + +import ( + "fmt" + + "github.com/hashicorp/go-memdb" +) + +var database *memdb.MemDB + +func CreateDatabase(ipinfos []IPInfo) error { + schema := &memdb.DBSchema{ + Tables: map[string]*memdb.TableSchema{ + "ipinfo": { + Name: "ipinfo", + Indexes: map[string]*memdb.IndexSchema{ + "id": { + Name: "id", + Unique: true, + Indexer: &memdb.UintFieldIndex{Field: "IPNumFrom"}, + }, + }, + }, + }, + } + + db, err := memdb.NewMemDB(schema) + if err != nil { + return err + } + + txn := db.Txn(true) + defer txn.Abort() + + for _, ipinfo := range ipinfos { + if err := txn.Insert("ipinfo", ipinfo); err != nil { + return err + } + } + + txn.Commit() + + database = db + return nil +} + +func SearchIPNet(ipnetnum uint) (*IPInfo, error) { + txn := database.Txn(false) + defer txn.Abort() + + raw, err := txn.First("ipinfo", "id", ipnetnum) + if err != nil { + return nil, err + } + if raw == nil { + return nil, nil + } + + var ipinfo IPInfo + for { + raw, err := txn.First("ipinfo", "id", ipnetnum) + if err != nil { + return nil, err + } + if raw != nil { + ipinfo = raw.(IPInfo) + break + } + if ipnetnum == 0 { + return nil, fmt.Errorf("SearchIPNet: IP net not found") + } + ipnetnum = ipnetnum - 256 + } + return &ipinfo, nil +} diff --git a/pkg/geoloc/main.go b/pkg/geoloc/main.go deleted file mode 100644 index 4e092fc..0000000 --- a/pkg/geoloc/main.go +++ /dev/null @@ -1,10 +0,0 @@ -package geoloc - -import "strings" - -func GetCountry(input string) *Country { - if c, exists := countries[strings.ToUpper(input)]; exists { - return &c - } - return nil -} diff --git a/pkg/geoloc/static.go b/pkg/geoloc/static.go new file mode 100644 index 0000000..b66bea0 --- /dev/null +++ b/pkg/geoloc/static.go @@ -0,0 +1,30 @@ +package geoloc + +import ( + "fmt" + "math" + "net" + "strings" + + "github.com/praserx/ipconv" +) + +func GetCountry(input string) *IPInfo { + if c, exists := countries[strings.ToUpper(input)]; exists { + return &c + } + return nil +} + +func GetIPInfo(ipaddress string) (uint, error) { + ip := net.ParseIP(ipaddress) + if ip == nil { + return 0, fmt.Errorf("no valid IP address") + } + ipnum, err := ipconv.IPv4ToInt(ip) + if err != nil { + return 0, err + } + ipnumfrom := uint(math.Floor(float64(ipnum)/float64(256))) * 256 + return ipnumfrom, nil +} diff --git a/pkg/geoloc/static_data.go b/pkg/geoloc/static_data.go new file mode 100644 index 0000000..031ceaf --- /dev/null +++ b/pkg/geoloc/static_data.go @@ -0,0 +1,1487 @@ +package geoloc + +var ( + countries = map[string]IPInfo{ + "AD": { + Country: "Andorra", + Code: "AD", + Latitude: 42.55, + Longitude: 1.6, + }, + "AE": { + Country: "United Arab Emirates", + Code: "AE", + Latitude: 23.42, + Longitude: 53.85, + }, + "AF": { + Country: "Afghanistan", + Code: "AF", + Latitude: 33.94, + Longitude: 67.71, + }, + "AG": { + Country: "Antigua And Barbuda", + Code: "AG", + Latitude: 17.06, + Longitude: -61.8, + }, + "AI": { + Country: "Anguilla", + Code: "AI", + Latitude: 18.22, + Longitude: -63.07, + }, + "AL": { + Country: "Albania", + Code: "AL", + Latitude: 41.15, + Longitude: 20.17, + }, + "AM": { + Country: "Armenia", + Code: "AM", + Latitude: 40.07, + Longitude: 45.04, + }, + "AN": { + Country: "Netherlands Antilles", + Code: "AN", + Latitude: 12.23, + Longitude: -69.06, + }, + "AO": { + Country: "Angola", + Code: "AO", + Latitude: -11.2, + Longitude: 17.87, + }, + "AR": { + Country: "Argentina", + Code: "AR", + Latitude: -38.42, + Longitude: -63.62, + }, + "AS": { + Country: "American Samoa", + Code: "AS", + Latitude: -14.27, + Longitude: -170.13, + }, + "AT": { + Country: "Austria", + Code: "AT", + Latitude: 47.52, + Longitude: 14.55, + }, + "AU": { + Country: "Australia", + Code: "AU", + Latitude: -25.27, + Longitude: 133.78, + }, + "AW": { + Country: "Aruba", + Code: "AW", + Latitude: 12.52, + Longitude: -69.97, + }, + "AX": { + Country: "Aland Islands", + Code: "AX", + Latitude: 60.18, + Longitude: 19.92, + }, + "AZ": { + Country: "Azerbaijan", + Code: "AZ", + Latitude: 40.14, + Longitude: 47.58, + }, + "BA": { + Country: "Bosnia And Herzegovina", + Code: "BA", + Latitude: 43.92, + Longitude: 17.68, + }, + "BB": { + Country: "Barbados", + Code: "BB", + Latitude: 13.19, + Longitude: -59.54, + }, + "BD": { + Country: "Bangladesh", + Code: "BD", + Latitude: 23.68, + Longitude: 90.36, + }, + "BE": { + Country: "Belgium", + Code: "BE", + Latitude: 50.5, + Longitude: 4.47, + }, + "BF": { + Country: "Burkina Faso", + Code: "BF", + Latitude: 12.24, + Longitude: -1.56, + }, + "BG": { + Country: "Bulgaria", + Code: "BG", + Latitude: 42.73, + Longitude: 25.49, + }, + "BH": { + Country: "Bahrain", + Code: "BH", + Latitude: 25.93, + Longitude: 50.64, + }, + "BI": { + Country: "Burundi", + Code: "BI", + Latitude: -3.37, + Longitude: 29.92, + }, + "BJ": { + Country: "Benin", + Code: "BJ", + Latitude: 9.31, + Longitude: 2.32, + }, + "BL": { + Country: "Saint Barthelemy", + Code: "BL", + Latitude: 17.9, + Longitude: -62.83, + }, + "BM": { + Country: "Bermuda", + Code: "BM", + Latitude: 32.32, + Longitude: -64.76, + }, + "BN": { + Country: "Brunei", + Code: "BN", + Latitude: 4.54, + Longitude: 114.73, + }, + "BO": { + Country: "Bolivia", + Code: "BO", + Latitude: -16.29, + Longitude: -63.59, + }, + "BQ": { + Country: "Bonaire", + Code: "BQ", + Latitude: 12.2, + Longitude: -68.26, + }, + "BR": { + Country: "Brazil", + Code: "BR", + Latitude: -14.24, + Longitude: -51.39, + }, + "BS": { + Country: "The Bahamas", + Code: "BS", + Latitude: 25.03, + Longitude: -77.4, + }, + "BT": { + Country: "Bhutan", + Code: "BT", + Latitude: 27.51, + Longitude: 90.43, + }, + "BV": { + Country: "Bouvet Island", + Code: "BV", + Latitude: -54.42, + Longitude: 3.41, + }, + "BW": { + Country: "Botswana", + Code: "BW", + Latitude: -22.33, + Longitude: 24.68, + }, + "BY": { + Country: "Belarus", + Code: "BY", + Latitude: 53.71, + Longitude: 27.95, + }, + "BZ": { + Country: "Belize", + Code: "BZ", + Latitude: 17.19, + Longitude: -88.5, + }, + "CA": { + Country: "Canada", + Code: "CA", + Latitude: 56.13, + Longitude: -106.35, + }, + "CC": { + Country: "Cocos (Keeling) Islands", + Code: "CC", + Latitude: -12.16, + Longitude: 96.87, + }, + "CD": { + Country: "Democratic Republic Of The Congo", + Code: "CD", + Latitude: -4.04, + Longitude: 21.76, + }, + "CF": { + Country: "Central African Republic", + Code: "CF", + Latitude: 6.61, + Longitude: 20.94, + }, + "CG": { + Country: "Republic Of The Congo", + Code: "CG", + Latitude: -0.23, + Longitude: 15.83, + }, + "CH": { + Country: "Switzerland", + Code: "CH", + Latitude: 46.82, + Longitude: 8.23, + }, + "CK": { + Country: "Cook Islands", + Code: "CK", + Latitude: -21.24, + Longitude: -159.78, + }, + "CL": { + Country: "Chile", + Code: "CL", + Latitude: -35.68, + Longitude: 71.54, + }, + "CM": { + Country: "Cameroon", + Code: "CM", + Latitude: 7.37, + Longitude: 12.35, + }, + "CN": { + Country: "China", + Code: "CN", + Latitude: 35.86, + Longitude: 104.2, + }, + "CO": { + Country: "Colombia", + Code: "CO", + Latitude: 4.57, + Longitude: -74.3, + }, + "CR": { + Country: "Costa Rica", + Code: "CR", + Latitude: 9.75, + Longitude: -83.75, + }, + "CU": { + Country: "Cuba", + Code: "CU", + Latitude: 21.52, + Longitude: -77.78, + }, + "CV": { + Country: "Cape Verde", + Code: "CV", + Latitude: 16, + Longitude: -24.01, + }, + "CW": { + Country: "Curacao", + Code: "CW", + Latitude: 12.17, + Longitude: -68.99, + }, + "CX": { + Country: "Christmas Island", + Code: "CX", + Latitude: -10.45, + Longitude: 105.69, + }, + "CY": { + Country: "Cyprus", + Code: "CY", + Latitude: 35.13, + Longitude: 33.43, + }, + "CZ": { + Country: "Czech Republic", + Code: "CZ", + Latitude: 49.82, + Longitude: 15.47, + }, + "DE": { + Country: "Germany", + Code: "DE", + Latitude: 51.17, + Longitude: 10.45, + }, + "DJ": { + Country: "Djibouti", + Code: "DJ", + Latitude: 11.83, + Longitude: 42.59, + }, + "DK": { + Country: "Denmark", + Code: "DK", + Latitude: 56.26, + Longitude: 9.5, + }, + "DM": { + Country: "Dominica", + Code: "DM", + Latitude: 15.41, + Longitude: -61.37, + }, + "DO": { + Country: "Dominican Republic", + Code: "DO", + Latitude: 18.74, + Longitude: -70.16, + }, + "DZ": { + Country: "Algeria", + Code: "DZ", + Latitude: 28.03, + Longitude: 1.66, + }, + "EC": { + Country: "Ecuador", + Code: "EC", + Latitude: -1.83, + Longitude: -78.18, + }, + "EE": { + Country: "Estonia", + Code: "EE", + Latitude: 58.6, + Longitude: 25.01, + }, + "EG": { + Country: "Egypt", + Code: "EG", + Latitude: 26.82, + Longitude: 30.8, + }, + "EH": { + Country: "Western Sahara", + Code: "EH", + Latitude: 24.22, + Longitude: -12.89, + }, + "ER": { + Country: "Eritrea", + Code: "ER", + Latitude: 15.18, + Longitude: 39.78, + }, + "ES": { + Country: "Spain", + Code: "ES", + Latitude: 40.46, + Longitude: -3.75, + }, + "ET": { + Country: "Ethiopia", + Code: "ET", + Latitude: 9.15, + Longitude: 40.49, + }, + "FI": { + Country: "Finland", + Code: "FI", + Latitude: 61.92, + Longitude: 25.75, + }, + "FJ": { + Country: "Fiji", + Code: "FJ", + Latitude: -16.58, + Longitude: 179.41, + }, + "FK": { + Country: "Falkland Islands", + Code: "FK", + Latitude: -51.8, + Longitude: 59.52, + }, + "FM": { + Country: "Micronesia", + Code: "FM", + Latitude: 7.43, + Longitude: 150.55, + }, + "FO": { + Country: "Faroe Islands", + Code: "FO", + Latitude: 61.89, + Longitude: -6.91, + }, + "FR": { + Country: "France", + Code: "FR", + Latitude: 46.23, + Longitude: 2.21, + }, + "GA": { + Country: "Gabon", + Code: "GA", + Latitude: -0.8, + Longitude: 11.61, + }, + "GB": { + Country: "United Kingdom", + Code: "GB", + Latitude: 55.38, + Longitude: -3.44, + }, + "GD": { + Country: "Grenada", + Code: "GD", + Latitude: 12.26, + Longitude: -61.6, + }, + "GE": { + Country: "Georgia", + Code: "GE", + Latitude: 42.32, + Longitude: 43.36, + }, + "GF": { + Country: "French Guiana", + Code: "GF", + Latitude: 3.93, + Longitude: -53.13, + }, + "GG": { + Country: "Guernsey", + Code: "GG", + Latitude: 49.47, + Longitude: -2.59, + }, + "GH": { + Country: "Ghana", + Code: "GH", + + Latitude: 7.95, + Longitude: -1.02, + }, + "GI": { + Country: "Gibraltar", + Code: "GI", + Latitude: 36.14, + Longitude: -5.35, + }, + "GL": { + Country: "Greenland", + Code: "GL", + Latitude: 71.71, + Longitude: 42.6, + }, + "GM": { + Country: "Gambia", + Code: "GM", + Latitude: 13.44, + Longitude: -15.31, + }, + "GN": { + Country: "Guinea", + Code: "GN", + Latitude: 9.95, + Longitude: -9.7, + }, + "GP": { + Country: "Guadeloupe", + Code: "GP", + Latitude: 17, + Longitude: -62.07, + }, + "GQ": { + Country: "Equatorial Guinea", + Code: "GQ", + Latitude: 1.65, + Longitude: 10.27, + }, + "GR": { + Country: "Greece", + Code: "GR", + Latitude: 39.07, + Longitude: 21.82, + }, + "GS": { + Country: "South Georgia And The South Sandwich Islands", + Code: "GS", + Latitude: -54.43, + Longitude: -36.59, + }, + "GT": { + Country: "Guatemala", + Code: "GT", + Latitude: 15.78, + Longitude: -90.23, + }, + "GU": { + Country: "Guam", + Code: "GU", + Latitude: 13.44, + Longitude: 144.79, + }, + "GW": { + Country: "Guinea-Bissau", + Code: "GW", + Latitude: 11.8, + Longitude: -15.18, + }, + "GY": { + Country: "Guyana", + Code: "GY", + Latitude: 4.86, + Longitude: -58.93, + }, + "HK": { + Country: "Hong Kong", + Code: "HK", + Latitude: 22.4, + Longitude: 114.11, + }, + "HN": { + Country: "Honduras", + Code: "HN", + Latitude: 15.2, + Longitude: -86.24, + }, + "HR": { + Country: "Croatia", + Code: "HR", + Latitude: 45.1, + Longitude: 15.2, + }, + "HT": { + Country: "Haiti", + Code: "HT", + Latitude: 18.97, + Longitude: -72.29, + }, + "HU": { + Country: "Hungary", + Code: "HU", + Latitude: 47.16, + Longitude: 19.5, + }, + "ID": { + Country: "Indonesia", + Code: "ID", + Latitude: -0.79, + Longitude: 113.92, + }, + "IE": { + Country: "Ireland", + Code: "IE", + Latitude: 53.41, + Longitude: -8.24, + }, + "IL": { + Country: "Israel", + Code: "IL", + Latitude: 31.05, + Longitude: 34.85, + }, + "IM": { + Country: "Isle Of Man", + Code: "IM", + Latitude: 54.24, + Longitude: -4.55, + }, + "IN": { + Country: "India", + Code: "IN", + Latitude: 20.59, + Longitude: 78.96, + }, + "IO": { + Country: "British Indian Ocean Territory", + Code: "IO", + Latitude: -6.34, + Longitude: 71.88, + }, + "IQ": { + Country: "Iraq", + Code: "IQ", + Latitude: 33.22, + Longitude: 43.68, + }, + "IR": { + Country: "Iran", + Code: "IR", + Latitude: 32.43, + Longitude: 53.69, + }, + "IS": { + Country: "Iceland", + Code: "IS", + Latitude: 64.96, + Longitude: -19.02, + }, + "IT": { + Country: "Italy", + Code: "IT", + Latitude: 41.87, + Longitude: 12.57, + }, + "JE": { + Country: "Jersey", + Code: "JE", + Latitude: 49.21, + Longitude: -2.13, + }, + "JM": { + Country: "Jamaica", + Code: "JM", + Latitude: 18.11, + Longitude: -77.3, + }, + "JO": { + Country: "Jordan", + Code: "JO", + Latitude: 30.59, + Longitude: 36.24, + }, + "JP": { + Country: "Japan", + Code: "JP", + Latitude: 36.2, + Longitude: 138.25, + }, + "KE": { + Country: "Kenya", + Code: "KE", + Latitude: -0.02, + Longitude: 37.91, + }, + "KG": { + Country: "Kyrgyzstan", + Code: "KG", + Latitude: 41.2, + Longitude: 74.77, + }, + "KH": { + Country: "Cambodia", + Code: "KH", + Latitude: 12.57, + Longitude: 104.99, + }, + "KI": { + Country: "Kiribati", + Code: "KI", + Latitude: -3.37, + Longitude: -168.73, + }, + "KM": { + Country: "Comoros", + Code: "KM", + Latitude: -11.88, + Longitude: 43.87, + }, + "KN": { + Country: "Saint Kitts And Nevis", + Code: "KN", + Latitude: 17.36, + Longitude: -62.78, + }, + "KP": { + Country: "North Korea", + Code: "KP", + Latitude: 40.34, + Longitude: 127.51, + }, + "KR": { + Country: "South Korea", + Code: "KR", + Latitude: 35.91, + Longitude: 127.77, + }, + "KW": { + Country: "Kuwait", + Code: "KW", + Latitude: 29.31, + Longitude: 47.48, + }, + "KY": { + Country: "Cayman Islands", + Code: "KY", + Latitude: 19.51, + Longitude: -80.57, + }, + "KZ": { + Country: "Kazakhstan", + Code: "KZ", + Latitude: 48.02, + Longitude: 66.92, + }, + "LA": { + Country: "Laos", + Code: "LA", + Latitude: 19.86, + Longitude: 102.5, + }, + "LB": { + Country: "Lebanon", + Code: "LB", + Latitude: 33.85, + Longitude: 35.86, + }, + "LC": { + Country: "Saint Lucia", + Code: "LC", + Latitude: 13.91, + Longitude: -60.98, + }, + "LI": { + Country: "Liechtenstein", + Code: "LI", + Latitude: 47.17, + Longitude: 9.56, + }, + "LK": { + Country: "Sri Lanka", + Code: "LK", + Latitude: 7.87, + Longitude: 80.77, + }, + "LR": { + Country: "Liberia", + Code: "LR", + Latitude: 6.43, + Longitude: -9.43, + }, + "LS": { + Country: "Lesotho", + Code: "LS", + Latitude: -29.61, + Longitude: 28.23, + }, + "LT": { + Country: "Lithuania", + Code: "LT", + Latitude: 55.17, + Longitude: 23.88, + }, + "LU": { + Country: "Luxembourg", + Code: "LU", + Latitude: 49.82, + Longitude: 6.13, + }, + "LV": { + Country: "Latvia", + Code: "LV", + Latitude: 56.88, + Longitude: 24.6, + }, + "LY": { + Country: "Libya", + Code: "LY", + Latitude: 26.34, + Longitude: 17.23, + }, + "MA": { + Country: "Morocco", + Code: "MA", + Latitude: 31.79, + Longitude: -7.09, + }, + "MC": { + Country: "Monaco", + Code: "MC", + Latitude: 43.75, + Longitude: 7.41, + }, + "MD": { + Country: "Moldova", + Code: "MD", + Latitude: 47.41, + Longitude: 28.37, + }, + "ME": { + Country: "Montenegro", + Code: "ME", + Latitude: 42.71, + Longitude: 19.37, + }, + "MF": { + Country: "Saint Martin", + Code: "MF", + Latitude: 18.07, + Longitude: -63.05, + }, + "MG": { + Country: "Madagascar", + Code: "MG", + Latitude: -18.77, + Longitude: 46.87, + }, + "MH": { + Country: "Marshall Islands", + Code: "MH", + Latitude: 7.13, + Longitude: 171.18, + }, + "MK": { + Country: "Macedonia", + Code: "MK", + Latitude: 41.61, + Longitude: 21.75, + }, + "ML": { + Country: "Mali", + Code: "ML", + Latitude: 17.57, + Longitude: -4, + }, + "MM": { + Country: "Myanmar (Burma)", + Code: "MM", + Latitude: 21.91, + Longitude: 95.96, + }, + "MN": { + Country: "Mongolia", + Code: "MN", + Latitude: 46.86, + Longitude: 103.85, + }, + "MO": { + Country: "Macau", + Code: "MO", + Latitude: 22.2, + Longitude: 113.54, + }, + "MP": { + Country: "Northern Mariana Islands", + Code: "MP", + Latitude: 17.33, + Longitude: 145.38, + }, + "MQ": { + Country: "Martinique", + Code: "MQ", + Latitude: 14.64, + Longitude: 61.02, + }, + "MR": { + Country: "Mauritania", + Code: "MR", + Latitude: 21.01, + Longitude: -10.94, + }, + "MS": { + Country: "Montserrat", + Code: "MS", + Latitude: 16.74, + Longitude: -62.19, + }, + "MT": { + Country: "Malta", + Code: "MT", + Latitude: 35.94, + Longitude: 14.38, + }, + "MU": { + Country: "Mauritius", + Code: "MU", + Latitude: -20.35, + Longitude: 57.55, + }, + "MV": { + Country: "Maldives", + Code: "MV", + Latitude: 3.2, + Longitude: 73.22, + }, + "MW": { + Country: "Malawi", + Code: "MW", + Latitude: -13.25, + Longitude: 34.3, + }, + "MX": { + Country: "Mexico", + Code: "MX", + Latitude: 23.63, + Longitude: -102.55, + }, + "MY": { + Country: "Malaysia", + Code: "MY", + Latitude: 4.21, + Longitude: 101.98, + }, + "MZ": { + Country: "Mozambique", + Code: "MZ", + Latitude: -18.67, + Longitude: 35.53, + }, + "NA": { + Country: "Namibia", + Code: "NA", + Latitude: -22.96, + Longitude: 18.49, + }, + "NC": { + Country: "New Caledonia", + Code: "NC", + Latitude: -20.9, + Longitude: 165.62, + }, + "NE": { + Country: "Niger", + Code: "NE", + Latitude: 17.61, + Longitude: 8.08, + }, + "NF": { + Country: "Norfolk Island", + Code: "NF", + Latitude: -29.04, + Longitude: 167.95, + }, + "NG": { + Country: "Nigeria", + Code: "NG", + Latitude: 9.08, + Longitude: 8.68, + }, + "NI": { + Country: "Nicaragua", + Code: "NI", + Latitude: 12.87, + Longitude: -85.21, + }, + "NL": { + Country: "Netherlands", + Code: "NL", + Latitude: 52.13, + Longitude: 5.29, + }, + "NO": { + Country: "Norway", + Code: "NO", + Latitude: 60.47, + Longitude: 8.47, + }, + "NP": { + Country: "Nepal", + Code: "NP", + Latitude: 28.39, + Longitude: 84.12, + }, + "NR": { + Country: "Nauru", + Code: "NR", + Latitude: -0.52, + Longitude: 166.93, + }, + "NU": { + Country: "Niue", + Code: "NU", + Latitude: -19.05, + Longitude: -169.87, + }, + "NZ": { + Country: "New Zealand", + Code: "NZ", + Latitude: -40.9, + Longitude: 174.89, + }, + "OM": { + Country: "Oman", + Code: "OM", + Latitude: 21.51, + Longitude: 55.92, + }, + "PA": { + Country: "Panama", + Code: "PA", + Latitude: 8.54, + Longitude: -80.78, + }, + "PE": { + Country: "Peru", + Code: "PE", + Latitude: -9.19, + Longitude: -75.02, + }, + "PF": { + Country: "French Polynesia", + Code: "PF", + Latitude: -17.68, + Longitude: -149.41, + }, + "PG": { + Country: "Papua New Guinea", + Code: "PG", + Latitude: -6.31, + Longitude: 143.96, + }, + "PH": { + Country: "Philippines", + Code: "PH", + Latitude: 12.88, + Longitude: 121.77, + }, + "PK": { + Country: "Pakistan", + Code: "PK", + Latitude: 30.38, + Longitude: 69.35, + }, + "PL": { + Country: "Poland", + Code: "PL", + Latitude: 51.92, + Longitude: 19.15, + }, + "PM": { + Country: "Saint Pierre And Miquelon", + Code: "PM", + Latitude: 46.94, + Longitude: -56.27, + }, + "PN": { + Country: "Pitcairn Islands", + Code: "PN", + Latitude: -24.7, + Longitude: -127.44, + }, + "PR": { + Country: "Puerto Rico", + Code: "PR", + Latitude: 18.22, + Longitude: -66.59, + }, + "PT": { + Country: "Portugal", + Code: "PT", + Latitude: 39.4, + Longitude: -8.22, + }, + "PW": { + Country: "Palau", + Code: "PW", + Latitude: 7.51, + Longitude: 134.58, + }, + "PY": { + Country: "Paraguay", + Code: "PY", + Latitude: -23.44, + Longitude: -58.44, + }, + "QA": { + Country: "Qatar", + Code: "QA", + Latitude: 25.35, + Longitude: 51.18, + }, + "RE": { + Country: "Reunion", + Code: "RE", + + Latitude: -21.12, + Longitude: 55.54, + }, + "RO": { + Country: "Romania", + Code: "RO", + + Latitude: 45.94, + Longitude: 24.97, + }, + "RS": { + Country: "Serbia", + Code: "RS", + + Latitude: 44.02, + Longitude: 21.01, + }, + "RU": { + Country: "Russia", + Code: "RU", + + Latitude: 61.52, + Longitude: 105.32, + }, + "RW": { + Country: "Rwanda", + Code: "RW", + + Latitude: -1.94, + Longitude: 29.87, + }, + "SA": { + Country: "Saudi Arabia", + Code: "SA", + + Latitude: 23.89, + Longitude: 45.08, + }, + "SB": { + Country: "Solomon Islands", + Code: "SB", + + Latitude: -9.65, + Longitude: 160.16, + }, + "SC": { + Country: "Seychelles", + Code: "SC", + + Latitude: -4.68, + Longitude: 55.49, + }, + "SD": { + Country: "Sudan", + Code: "SD", + + Latitude: 12.86, + Longitude: 30.22, + }, + "SE": { + Country: "Sweden", + Code: "SE", + + Latitude: 60.13, + Longitude: 18.64, + }, + "SG": { + Country: "Singapore", + Code: "SG", + + Latitude: 1.35, + Longitude: 103.82, + }, + "SH": { + Country: "Saint Helena", + Code: "SH", + + Latitude: -24.14, + Longitude: -10.03, + }, + "SI": { + Country: "Slovenia", + Code: "SI", + + Latitude: 46.15, + Longitude: 15, + }, + "SJ": { + Country: "Svalbard And Jan Mayen", + Code: "SJ", + + Latitude: 77.55, + Longitude: 23.67, + }, + "SK": { + Country: "Slovakia", + Code: "SK", + + Latitude: 48.67, + Longitude: 19.7, + }, + "SL": { + Country: "Sierra Leone", + Code: "SL", + + Latitude: 8.46, + Longitude: -11.78, + }, + "SM": { + Country: "San Marino", + Code: "SM", + Latitude: 43.94, + Longitude: 12.46, + }, + "SN": { + Country: "Senegal", + Code: "SN", + Latitude: 14.5, + Longitude: -14.45, + }, + "SO": { + Country: "Somalia", + Code: "SO", + Latitude: 5.15, + Longitude: 46.2, + }, + "SR": { + Country: "SuriCountry", + Code: "SR", + Latitude: 3.92, + Longitude: -56.03, + }, + "ST": { + Country: "Sao Tome And Principe", + Code: "ST", + Latitude: 0.19, + Longitude: 6.61, + }, + "SV": { + Country: "El Salvador", + Code: "SV", + Latitude: 13.79, + Longitude: -88.9, + }, + "SX": { + Country: "Sint Maarten", + Code: "SX", + Latitude: 18.03, + Longitude: -63.05, + }, + "SY": { + Country: "Syria", + Code: "SY", + Latitude: 34.8, + Longitude: 39, + }, + "SZ": { + Country: "Swaziland", + Code: "SZ", + Latitude: -26.52, + Longitude: 31.47, + }, + "TC": { + Country: "Turks And Caicos Islands", + Code: "TC", + Latitude: 21.69, + Longitude: -71.8, + }, + "TD": { + Country: "Chad", + Code: "TD", + Latitude: 15.45, + Longitude: 18.73, + }, + "TG": { + Country: "Togo", + Code: "TG", + Latitude: 8.62, + Longitude: 0.82, + }, + "TH": { + Country: "Thailand", + Code: "TH", + Latitude: 15.87, + Longitude: 100.99, + }, + "TJ": { + Country: "Tajikistan", + Code: "TJ", + Latitude: 38.86, + Longitude: 71.28, + }, + "TK": { + Country: "Tokelau", + Code: "TK", + Latitude: -8.97, + Longitude: -171.86, + }, + "TL": { + Country: "Timor-Leste", + Code: "TL", + Latitude: -8.87, + Longitude: 125.73, + }, + "TM": { + Country: "Turkmenistan", + Code: "TM", + Latitude: 38.97, + Longitude: 59.56, + }, + "TN": { + Country: "Tunisia", + Code: "TN", + Latitude: 33.89, + Longitude: 9.54, + }, + "TO": { + Country: "Tonga", + Code: "TO", + Latitude: -21.18, + Longitude: -175.2, + }, + "TR": { + Country: "Turkey", + Code: "TR", + Latitude: 38.96, + Longitude: 35.24, + }, + "TT": { + Country: "Trinidad And Tobago", + Code: "TT", + Latitude: 10.69, + Longitude: -61.22, + }, + "TV": { + Country: "Tuvalu", + Code: "TV", + Latitude: -7.11, + Longitude: 177.65, + }, + "TW": { + Country: "Taiwan", + Code: "TW", + Latitude: 23.7, + Longitude: 120.96, + }, + "TZ": { + Country: "Tanzania", + Code: "TZ", + Latitude: -6.37, + Longitude: 34.89, + }, + "UA": { + Country: "Ukraine", + Code: "UA", + Latitude: 48.38, + Longitude: 31.17, + }, + "UG": { + Country: "Uganda", + Code: "UG", + Latitude: 1.37, + Longitude: 32.29, + }, + "US": { + Country: "United States Of America", + Code: "US", + Latitude: 37.09, + Longitude: -95.71, + }, + "UY": { + Country: "Uruguay", + Code: "UY", + Latitude: -32.52, + Longitude: -55.77, + }, + "UZ": { + Country: "Uzbekistan", + Code: "UZ", + Latitude: 41.38, + Longitude: 64.59, + }, + "VA": { + Country: "Vatican City", + Code: "VA", + Latitude: 41.9, + Longitude: 12.45, + }, + "VC": { + Country: "Saint Vincent And The Grenadines", + Code: "VC", + Latitude: 12.98, + Longitude: -61.29, + }, + "VE": { + Country: "Venezuela", + Code: "VE", + Latitude: 6.42, + Longitude: -66.59, + }, + "VG": { + Country: "British Virgin Islands", + Code: "VG", + Latitude: 18.42, + Longitude: -64.64, + }, + "VI": { + Country: "US Virgin Islands", + Code: "VI", + Latitude: 18.34, + Longitude: -64.9, + }, + "VN": { + Country: "Vietnam", + Code: "VN", + Latitude: 14.06, + Longitude: 108.28, + }, + "VU": { + Country: "Vanuatu", + Code: "VU", + Latitude: -15.38, + Longitude: 166.96, + }, + "WF": { + Country: "Wallis And Futuna", + Code: "WF", + Latitude: -13.77, + Longitude: -177.16, + }, + "WS": { + Country: "Samoa", + Code: "WS", + Latitude: -13.76, + Longitude: -172.1, + }, + "XK": { + Country: "Kosovo", + Code: "XK", + Latitude: 42.6, + Longitude: 20.9, + }, + "YE": { + Country: "Yemen", + Code: "YE", + Latitude: 15.55, + Longitude: 48.52, + }, + "YT": { + Country: "Mayotte", + Code: "YT", + Latitude: -12.83, + Longitude: 45.17, + }, + "ZA": { + Country: "South Africa", + Code: "ZA", + Latitude: -30.56, + Longitude: 22.94, + }, + "ZM": { + Country: "Zambia", + Code: "ZM", + Latitude: -13.13, + Longitude: 27.85, + }, + "ZW": { + Country: "Zimbabwe", + Code: "ZW", + Latitude: -19.02, + Longitude: 29.15, + }, + } +) diff --git a/pkg/geoloc/main_test.go b/pkg/geoloc/static_test.go similarity index 64% rename from pkg/geoloc/main_test.go rename to pkg/geoloc/static_test.go index c0045fa..a6c79a3 100644 --- a/pkg/geoloc/main_test.go +++ b/pkg/geoloc/static_test.go @@ -12,7 +12,7 @@ func TestGetCountry(t *testing.T) { tests := []struct { name string args args - want *Country + want *IPInfo }{ {"GBR Test", args{input: "826"}, nil}, {"USA upper Test", args{input: "USA"}, nil}, @@ -31,3 +31,23 @@ func TestGetCountry(t *testing.T) { }) } } + +func TestGetIPInfo(t *testing.T) { + type args struct { + input string + } + tests := []struct { + name string + args args + want uint + }{ + {"IP address Test", args{input: "1.1.1.1"}, 16843008}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got, err := GetIPInfo(tt.args.input); err != nil || !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetIPInfo() - %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/geoloc/types.go b/pkg/geoloc/types.go new file mode 100644 index 0000000..dca98c8 --- /dev/null +++ b/pkg/geoloc/types.go @@ -0,0 +1,12 @@ +package geoloc + +type IPInfo struct { + IPNumFrom uint `json:"ip_num_min"` + IPNumTo uint `json:"ip_num_max"` + Code string `json:"code"` + Country string `json:"country"` + State string `json:"state"` + City string `json:"city"` + Latitude float32 `json:"latitude"` + Longitude float32 `json:"longitude"` +} diff --git a/renovate.json b/renovate.json index fe94537..97b15e3 100644 --- a/renovate.json +++ b/renovate.json @@ -1,5 +1,9 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:base", + "regexManagers:dockerfileVersions" + ], "packageRules": [ { "matchPackagePatterns": ["*"],