2020-11-20 12:38:12 +01:00
|
|
|
package eureka
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/xml"
|
|
|
|
"fmt"
|
|
|
|
"strconv"
|
|
|
|
|
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promauth"
|
2020-12-24 09:52:37 +01:00
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promscrape/discoveryutils"
|
2020-12-24 09:56:10 +01:00
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/proxy"
|
2020-11-20 12:38:12 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
const appsAPIPath = "/apps"
|
|
|
|
|
|
|
|
// SDConfig represents service discovery config for eureka.
|
|
|
|
//
|
|
|
|
// See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#eureka
|
|
|
|
type SDConfig struct {
|
|
|
|
Server string `yaml:"server,omitempty"`
|
|
|
|
Token *string `yaml:"token"`
|
|
|
|
Datacenter string `yaml:"datacenter"`
|
|
|
|
Scheme string `yaml:"scheme,omitempty"`
|
|
|
|
Username string `yaml:"username"`
|
|
|
|
Password string `yaml:"password"`
|
2020-12-24 09:56:10 +01:00
|
|
|
ProxyURL proxy.URL `yaml:"proxy_url,omitempty"`
|
2020-11-20 12:38:12 +01:00
|
|
|
TLSConfig *promauth.TLSConfig `yaml:"tls_config,omitempty"`
|
|
|
|
// RefreshInterval time.Duration `yaml:"refresh_interval"`
|
|
|
|
// refresh_interval is obtained from `-promscrape.ec2SDCheckInterval` command-line option.
|
|
|
|
Port *int `yaml:"port,omitempty"`
|
|
|
|
}
|
2020-11-20 13:00:12 +01:00
|
|
|
|
2020-11-20 12:38:12 +01:00
|
|
|
type applications struct {
|
|
|
|
Applications []Application `xml:"application"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Application - eureka application https://github.com/Netflix/eureka/wiki/Eureka-REST-operations/
|
|
|
|
type Application struct {
|
|
|
|
Name string `xml:"name"`
|
|
|
|
Instances []Instance `xml:"instance"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Port - eureka instance port.
|
|
|
|
type Port struct {
|
|
|
|
Port int `xml:",chardata"`
|
|
|
|
Enabled bool `xml:"enabled,attr"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Instance - eureka instance https://github.com/Netflix/eureka/wiki/Eureka-REST-operations
|
|
|
|
type Instance struct {
|
|
|
|
HostName string `xml:"hostName"`
|
|
|
|
HomePageURL string `xml:"homePageUrl"`
|
|
|
|
StatusPageURL string `xml:"statusPageUrl"`
|
|
|
|
HealthCheckURL string `xml:"healthCheckUrl"`
|
|
|
|
App string `xml:"app"`
|
|
|
|
IPAddr string `xml:"ipAddr"`
|
|
|
|
VipAddress string `xml:"vipAddress"`
|
|
|
|
SecureVipAddress string `xml:"secureVipAddress"`
|
|
|
|
Status string `xml:"status"`
|
|
|
|
Port Port `xml:"port"`
|
|
|
|
SecurePort Port `xml:"securePort"`
|
|
|
|
DataCenterInfo DataCenterInfo `xml:"dataCenterInfo"`
|
|
|
|
Metadata MetaData `xml:"metadata"`
|
|
|
|
CountryID int `xml:"countryId"`
|
|
|
|
InstanceID string `xml:"instanceId"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// MetaData - eureka objects metadata.
|
|
|
|
type MetaData struct {
|
|
|
|
Items []Tag `xml:",any"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tag - eureka metadata tag - list of k/v values.
|
|
|
|
type Tag struct {
|
|
|
|
XMLName xml.Name
|
|
|
|
Content string `xml:",innerxml"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// DataCenterInfo -eureka datacentre metadata
|
|
|
|
type DataCenterInfo struct {
|
|
|
|
Name string `xml:"name"`
|
|
|
|
Metadata MetaData `xml:"metadata"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetLabels returns Eureka labels according to sdc.
|
|
|
|
func GetLabels(sdc *SDConfig, baseDir string) ([]map[string]string, error) {
|
|
|
|
cfg, err := getAPIConfig(sdc, baseDir)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("cannot get API config: %w", err)
|
|
|
|
}
|
|
|
|
data, err := getAPIResponse(cfg, appsAPIPath)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
apps, err := parseAPIResponse(data)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-11-20 13:00:12 +01:00
|
|
|
port := 80
|
|
|
|
if sdc.Port != nil {
|
|
|
|
port = *sdc.Port
|
|
|
|
}
|
|
|
|
return addInstanceLabels(apps, port), nil
|
2020-11-20 12:38:12 +01:00
|
|
|
}
|
|
|
|
|
2020-11-20 13:00:12 +01:00
|
|
|
func addInstanceLabels(apps *applications, port int) []map[string]string {
|
2020-11-20 12:38:12 +01:00
|
|
|
var ms []map[string]string
|
2020-11-20 13:00:12 +01:00
|
|
|
for _, app := range apps.Applications {
|
2020-11-20 12:38:12 +01:00
|
|
|
for _, instance := range app.Instances {
|
2020-11-20 13:00:12 +01:00
|
|
|
instancePort := port
|
|
|
|
if instance.Port.Port != 0 {
|
|
|
|
instancePort = instance.Port.Port
|
2020-11-20 12:38:12 +01:00
|
|
|
}
|
2020-11-20 13:00:12 +01:00
|
|
|
targetAddress := discoveryutils.JoinHostPort(instance.HostName, instancePort)
|
2020-11-20 12:38:12 +01:00
|
|
|
m := map[string]string{
|
2020-11-20 13:00:12 +01:00
|
|
|
"__address__": targetAddress,
|
|
|
|
"instance": instance.InstanceID,
|
|
|
|
"__meta_eureka_app_name": app.Name,
|
|
|
|
"__meta_eureka_app_instance_hostname": instance.HostName,
|
|
|
|
"__meta_eureka_app_instance_homepage_url": instance.HomePageURL,
|
|
|
|
"__meta_eureka_app_instance_statuspage_url": instance.StatusPageURL,
|
|
|
|
"__meta_eureka_app_instance_healthcheck_url": instance.HealthCheckURL,
|
|
|
|
"__meta_eureka_app_instance_ip_addr": instance.IPAddr,
|
|
|
|
"__meta_eureka_app_instance_vip_address": instance.VipAddress,
|
|
|
|
"__meta_eureka_app_instance_secure_vip_address": instance.SecureVipAddress,
|
|
|
|
"__meta_eureka_app_instance_status": instance.Status,
|
|
|
|
"__meta_eureka_app_instance_country_id": strconv.Itoa(instance.CountryID),
|
|
|
|
"__meta_eureka_app_instance_id": instance.InstanceID,
|
2020-11-20 12:38:12 +01:00
|
|
|
}
|
2020-11-20 13:00:12 +01:00
|
|
|
if instance.Port.Port != 0 {
|
2020-11-20 12:38:12 +01:00
|
|
|
m["__meta_eureka_app_instance_port"] = strconv.Itoa(instance.Port.Port)
|
|
|
|
m["__meta_eureka_app_instance_port_enabled"] = strconv.FormatBool(instance.Port.Enabled)
|
|
|
|
}
|
2020-11-20 13:00:12 +01:00
|
|
|
if instance.SecurePort.Port != 0 {
|
2020-11-20 12:38:12 +01:00
|
|
|
m["__meta_eureka_app_instance_secure_port"] = strconv.Itoa(instance.SecurePort.Port)
|
|
|
|
m["__meta_eureka_app_instance_secure_port_enabled"] = strconv.FormatBool(instance.SecurePort.Enabled)
|
|
|
|
|
|
|
|
}
|
|
|
|
if len(instance.DataCenterInfo.Name) > 0 {
|
|
|
|
m["__meta_eureka_app_instance_datacenterinfo_name"] = instance.DataCenterInfo.Name
|
|
|
|
for _, tag := range instance.DataCenterInfo.Metadata.Items {
|
|
|
|
m["__meta_eureka_app_instance_datacenterinfo_metadata_"+discoveryutils.SanitizeLabelName(tag.XMLName.Local)] = tag.Content
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, tag := range instance.Metadata.Items {
|
|
|
|
m["__meta_eureka_app_instance_metadata_"+discoveryutils.SanitizeLabelName(tag.XMLName.Local)] = tag.Content
|
|
|
|
}
|
|
|
|
ms = append(ms, m)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ms
|
|
|
|
}
|