/
latlon.go
108 lines (86 loc) · 2.19 KB
/
latlon.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright 2018 National Technology & Engineering Solutions of Sandia, LLC
// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S.
// Government retains certain rights in this software.
package main
import (
"flag"
"strconv"
"strings"
"pkg/commands"
"pkg/latlon"
log "pkg/minilog"
)
type CommandLatLon struct {
commands.Base // embed
dir string
}
func init() {
base := commands.Base{
Flags: flag.NewFlagSet("latlon", flag.ExitOnError),
Usage: "latlon [OPTION]...",
Short: "annotate with geoip information",
Long: `
Annotates nodes using a GeoIP database and node IP addresses. Adds latitude,
longitude, country and ISP information to each node.
`,
}
cmd := &CommandLatLon{Base: base}
cmd.Flags.StringVar(&cmd.dir, "dir", "", "directory to scan for geoip files (*.mmdb)")
commands.Append(cmd)
}
func (c *CommandLatLon) Run() error {
db, err := latlon.Open(c.dir)
if err != nil {
return err
}
defer db.Close()
endpoints, err := dc.GetEndpoints("", "")
if err != nil {
return err
}
for _, v := range endpoints {
ips := GetIPs(v)
if len(ips) == 0 {
log.Error("no ip on endpoint: %v", v.NID)
continue
}
// TODO: should we annotate with a location per IP instead of the first
// IP with a valid location?
var res *latlon.Result
for _, ip := range ips {
res2, err := db.Lookup(ips[0])
if err != nil {
log.Error("unable to lookup %v: %v", ip, err)
continue
}
res = res2
break
}
if res == nil {
continue
}
parts := []string{}
if s := res.City.City.Names["en"]; s != "" {
parts = append(parts, s)
}
for _, s := range res.City.Subdivisions {
parts = append(parts, s.Names["en"])
}
if s := res.City.Country.Names["en"]; s != "" {
parts = append(parts, s)
}
if len(parts) > 0 {
v.D["geoip_location"] = strings.Join(parts, ", ")
}
v.D["geoip_lat"] = strconv.FormatFloat(res.City.Location.Latitude, 'f', -1, 64)
v.D["geoip_lon"] = strconv.FormatFloat(res.City.Location.Longitude, 'f', -1, 64)
v.D["geoip_isp"] = res.ISP.ISP
if s := res.City.Country.IsoCode; s != "" {
v.D["geoip_country"] = strings.ToUpper(s)
}
if err := UpdateEndpoint(v); err != nil {
return err
}
}
return nil
}