VictoriaMetrics/lib/promscrape/discovery/kubernetes/ingress.go
Aliaksandr Valialkin c8f2f9b2e8 lib/promscrape: cleanup after 9b2246c29b
Main points:

* Revert changes outside lib/promscrape/discovery/kuberntes . These changes can be applied later in a separate commit
* Minimize changes in lib/promscrape/discovery/kubernetes compared to a93e644001
* Corner case fixes.
2021-02-26 16:54:05 +02:00

154 lines
4.1 KiB
Go

package kubernetes
import (
"encoding/json"
"fmt"
)
// getIngressesLabels returns labels for k8s ingresses obtained from the given cfg.
func getIngressesLabels(cfg *apiConfig) []map[string]string {
igs := getIngresses(cfg)
var ms []map[string]string
for _, ig := range igs {
ms = ig.appendTargetLabels(ms)
}
return ms
}
func getIngresses(cfg *apiConfig) []*Ingress {
os := cfg.aw.getObjectsByRole("ingress")
igs := make([]*Ingress, len(os))
for i, o := range os {
igs[i] = o.(*Ingress)
}
return igs
}
func (ig *Ingress) key() string {
return ig.Metadata.key()
}
func parseIngressList(data []byte) (map[string]object, ListMeta, error) {
var igl IngressList
if err := json.Unmarshal(data, &igl); err != nil {
return nil, igl.Metadata, fmt.Errorf("cannot unmarshal IngressList from %q: %w", data, err)
}
objectsByKey := make(map[string]object)
for _, ig := range igl.Items {
objectsByKey[ig.key()] = ig
}
return objectsByKey, igl.Metadata, nil
}
func parseIngress(data []byte) (object, error) {
var ig Ingress
if err := json.Unmarshal(data, &ig); err != nil {
return nil, err
}
return &ig, nil
}
// IngressList represents ingress list in k8s.
//
// See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#ingresslist-v1beta1-extensions
type IngressList struct {
Metadata ListMeta
Items []*Ingress
}
// Ingress represents ingress in k8s.
//
// See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#ingress-v1beta1-extensions
type Ingress struct {
Metadata ObjectMeta
Spec IngressSpec
}
// IngressSpec represents ingress spec in k8s.
//
// See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#ingressspec-v1beta1-extensions
type IngressSpec struct {
TLS []IngressTLS `json:"tls"`
Rules []IngressRule
}
// IngressTLS represents ingress TLS spec in k8s.
//
// See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#ingresstls-v1beta1-extensions
type IngressTLS struct {
Hosts []string
}
// IngressRule represents ingress rule in k8s.
//
// See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#ingressrule-v1beta1-extensions
type IngressRule struct {
Host string
HTTP HTTPIngressRuleValue `json:"http"`
}
// HTTPIngressRuleValue represents HTTP ingress rule value in k8s.
//
// See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#httpingressrulevalue-v1beta1-extensions
type HTTPIngressRuleValue struct {
Paths []HTTPIngressPath
}
// HTTPIngressPath represents HTTP ingress path in k8s.
//
// See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#httpingresspath-v1beta1-extensions
type HTTPIngressPath struct {
Path string
}
// appendTargetLabels appends labels for Ingress ig to ms and returns the result.
//
// See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#ingress
func (ig *Ingress) appendTargetLabels(ms []map[string]string) []map[string]string {
tlsHosts := make(map[string]bool)
for _, tls := range ig.Spec.TLS {
for _, host := range tls.Hosts {
tlsHosts[host] = true
}
}
for _, r := range ig.Spec.Rules {
paths := getIngressRulePaths(r.HTTP.Paths)
scheme := "http"
if tlsHosts[r.Host] {
scheme = "https"
}
for _, path := range paths {
m := getLabelsForIngressPath(ig, scheme, r.Host, path)
ms = append(ms, m)
}
}
return ms
}
func getLabelsForIngressPath(ig *Ingress, scheme, host, path string) map[string]string {
m := map[string]string{
"__address__": host,
"__meta_kubernetes_namespace": ig.Metadata.Namespace,
"__meta_kubernetes_ingress_name": ig.Metadata.Name,
"__meta_kubernetes_ingress_scheme": scheme,
"__meta_kubernetes_ingress_host": host,
"__meta_kubernetes_ingress_path": path,
}
ig.Metadata.registerLabelsAndAnnotations("__meta_kubernetes_ingress", m)
return m
}
func getIngressRulePaths(paths []HTTPIngressPath) []string {
if len(paths) == 0 {
return []string{"/"}
}
var result []string
for _, p := range paths {
path := p.Path
if path == "" {
path = "/"
}
result = append(result, path)
}
return result
}