mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-29 10:26:29 +02:00
telemetry: try guess hostname or external IP addr for metrics (#2412)
This commit is contained in:
parent
94eb3c1149
commit
204aa30b6e
3 changed files with 81 additions and 15 deletions
67
internal/registry/hostname.go
Normal file
67
internal/registry/hostname.go
Normal file
|
@ -0,0 +1,67 @@
|
|||
package registry
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func isFQDN(host string) bool {
|
||||
return strings.Count(host, ".") > 1
|
||||
}
|
||||
|
||||
func chooseIP(ips []net.IP) net.IP {
|
||||
for _, ip := range ips {
|
||||
if !ip.IsLoopback() && !ip.IsInterfaceLocalMulticast() && !ip.IsLinkLocalUnicast() && !ip.IsLinkLocalMulticast() {
|
||||
return ip
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getViaLookup tries to lookup whether short hostname may be resolved into IP and back into a longer one
|
||||
func getViaLookup(host string) (string, error) {
|
||||
addrs, err := net.LookupIP(host)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(addrs) == 0 {
|
||||
return "", errors.New("address lookup failed")
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
hosts, err := net.LookupAddr(addr.String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, h := range hosts {
|
||||
h = strings.TrimSuffix(h, ".")
|
||||
if isFQDN(h) {
|
||||
return h, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ip := chooseIP(addrs); ip != nil {
|
||||
return ip.String(), nil
|
||||
}
|
||||
return "", errors.New("lookup failed")
|
||||
}
|
||||
|
||||
// getHostOrIP tries to fetch a publicly accessible IP address for the current host/container
|
||||
func getHostOrIP() (string, error) {
|
||||
host, err := os.Hostname()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("hostname: %w", err)
|
||||
}
|
||||
if isFQDN(host) {
|
||||
return host, nil
|
||||
}
|
||||
|
||||
if h, err := getViaLookup(host); err == nil {
|
||||
return h, nil
|
||||
}
|
||||
|
||||
return host, nil
|
||||
}
|
|
@ -81,9 +81,22 @@ func getReportedServices(cfg *config.Config) ([]*pb.Service, error) {
|
|||
}
|
||||
|
||||
func metricsURL(o config.Options) (*url.URL, error) {
|
||||
host, port, err := net.SplitHostPort(o.MetricsAddr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid metrics address %q: %w", o.MetricsAddr, err)
|
||||
}
|
||||
if port == "" {
|
||||
return nil, fmt.Errorf("invalid metrics value %q: port is required", o.MetricsAddr)
|
||||
}
|
||||
if host == "" {
|
||||
if host, err = getHostOrIP(); err != nil {
|
||||
return nil, fmt.Errorf("could not guess hostname: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
u := url.URL{
|
||||
Scheme: "http",
|
||||
Host: o.MetricsAddr,
|
||||
Host: net.JoinHostPort(host, port),
|
||||
Path: defaultMetricsPath,
|
||||
}
|
||||
|
||||
|
@ -107,19 +120,6 @@ func metricsURL(o config.Options) (*url.URL, error) {
|
|||
return nil, fmt.Errorf("no metrics address provided")
|
||||
}
|
||||
|
||||
host, port, err := net.SplitHostPort(o.MetricsAddr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid metrics address %q: %w", o.MetricsAddr, err)
|
||||
}
|
||||
|
||||
if port == "" {
|
||||
return nil, fmt.Errorf("invalid metrics value %q: port is required", o.MetricsAddr)
|
||||
}
|
||||
|
||||
if host == "" {
|
||||
return nil, fmt.Errorf("invalid metrics value %q: either host or IP address is required", o.MetricsAddr)
|
||||
}
|
||||
|
||||
return &u, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ func TestMetricsURL(t *testing.T) {
|
|||
for _, opt := range []config.Options{
|
||||
{MetricsAddr: "my.host:"},
|
||||
{MetricsAddr: "my.host:9090", MetricsBasicAuth: "SMTH"},
|
||||
{MetricsAddr: ":9090"},
|
||||
{MetricsAddr: "my.host"},
|
||||
} {
|
||||
_, err := metricsURL(opt)
|
||||
|
|
Loading…
Add table
Reference in a new issue