mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-25 21:54:10 -08:00
Kubernetes SD: Introduce ingressAdaptor
Signed-off-by: Takashi Kusumi <tkusumi@zlab.co.jp>
This commit is contained in:
parent
6634a570cf
commit
40981c422b
|
@ -114,26 +114,23 @@ func (i *Ingress) process(ctx context.Context, ch chan<- []*targetgroup.Group) b
|
|||
return true
|
||||
}
|
||||
|
||||
var ia ingressAdaptor
|
||||
switch ingress := o.(type) {
|
||||
case *v1.Ingress:
|
||||
send(ctx, ch, i.buildIngress(ingress))
|
||||
return true
|
||||
ia = newIngressAdaptorFromV1(ingress)
|
||||
case *v1beta1.Ingress:
|
||||
send(ctx, ch, i.buildIngressV1beta1(ingress))
|
||||
ia = newIngressAdaptorFromV1beta1(ingress)
|
||||
default:
|
||||
level.Error(i.logger).Log("msg", "converting to Ingress object failed", "err",
|
||||
errors.Errorf("received unexpected object: %v", o))
|
||||
return true
|
||||
}
|
||||
|
||||
level.Error(i.logger).Log("msg", "converting to Ingress object failed", "err",
|
||||
errors.Errorf("received unexpected object: %v", o))
|
||||
send(ctx, ch, i.buildIngress(ia))
|
||||
return true
|
||||
}
|
||||
|
||||
func ingressSource(s *v1.Ingress) string {
|
||||
return ingressSourceFromNamespaceAndName(s.Namespace, s.Name)
|
||||
}
|
||||
|
||||
func ingressSourceV1beta1(s *v1beta1.Ingress) string {
|
||||
return ingressSourceFromNamespaceAndName(s.Namespace, s.Name)
|
||||
func ingressSource(s ingressAdaptor) string {
|
||||
return ingressSourceFromNamespaceAndName(s.namespace(), s.name())
|
||||
}
|
||||
|
||||
func ingressSourceFromNamespaceAndName(namespace, name string) string {
|
||||
|
@ -152,22 +149,22 @@ const (
|
|||
ingressClassNameLabel = metaLabelPrefix + "ingress_class_name"
|
||||
)
|
||||
|
||||
func ingressLabels(ingress *v1.Ingress) model.LabelSet {
|
||||
func ingressLabels(ingress ingressAdaptor) model.LabelSet {
|
||||
// Each label and annotation will create two key-value pairs in the map.
|
||||
ls := make(model.LabelSet, 2*(len(ingress.Labels)+len(ingress.Annotations))+2)
|
||||
ls[ingressNameLabel] = lv(ingress.Name)
|
||||
ls[namespaceLabel] = lv(ingress.Namespace)
|
||||
if ingress.Spec.IngressClassName != nil {
|
||||
ls[ingressClassNameLabel] = lv(*ingress.Spec.IngressClassName)
|
||||
ls := make(model.LabelSet, 2*(len(ingress.labels())+len(ingress.annotations()))+2)
|
||||
ls[ingressNameLabel] = lv(ingress.name())
|
||||
ls[namespaceLabel] = lv(ingress.namespace())
|
||||
if cls := ingress.ingressClassName(); cls != nil {
|
||||
ls[ingressClassNameLabel] = lv(*cls)
|
||||
}
|
||||
|
||||
for k, v := range ingress.Labels {
|
||||
for k, v := range ingress.labels() {
|
||||
ln := strutil.SanitizeLabelName(k)
|
||||
ls[model.LabelName(ingressLabelPrefix+ln)] = lv(v)
|
||||
ls[model.LabelName(ingressLabelPresentPrefix+ln)] = presentValue
|
||||
}
|
||||
|
||||
for k, v := range ingress.Annotations {
|
||||
for k, v := range ingress.annotations() {
|
||||
ln := strutil.SanitizeLabelName(k)
|
||||
ls[model.LabelName(ingressAnnotationPrefix+ln)] = lv(v)
|
||||
ls[model.LabelName(ingressAnnotationPresentPrefix+ln)] = presentValue
|
||||
|
@ -175,37 +172,14 @@ func ingressLabels(ingress *v1.Ingress) model.LabelSet {
|
|||
return ls
|
||||
}
|
||||
|
||||
func ingressLabelsV1beta1(ingress *v1beta1.Ingress) model.LabelSet {
|
||||
// Each label and annotation will create two key-value pairs in the map.
|
||||
ls := make(model.LabelSet, 2*(len(ingress.Labels)+len(ingress.Annotations))+2)
|
||||
ls[ingressNameLabel] = lv(ingress.Name)
|
||||
ls[namespaceLabel] = lv(ingress.Namespace)
|
||||
if ingress.Spec.IngressClassName != nil {
|
||||
ls[ingressClassNameLabel] = lv(*ingress.Spec.IngressClassName)
|
||||
}
|
||||
|
||||
for k, v := range ingress.Labels {
|
||||
ln := strutil.SanitizeLabelName(k)
|
||||
ls[model.LabelName(ingressLabelPrefix+ln)] = lv(v)
|
||||
ls[model.LabelName(ingressLabelPresentPrefix+ln)] = presentValue
|
||||
}
|
||||
|
||||
for k, v := range ingress.Annotations {
|
||||
ln := strutil.SanitizeLabelName(k)
|
||||
ls[model.LabelName(ingressAnnotationPrefix+ln)] = lv(v)
|
||||
ls[model.LabelName(ingressAnnotationPresentPrefix+ln)] = presentValue
|
||||
}
|
||||
return ls
|
||||
}
|
||||
|
||||
func pathsFromIngressRule(rv *v1.IngressRuleValue) []string {
|
||||
if rv.HTTP == nil {
|
||||
func pathsFromIngressPaths(ingressPaths []string) []string {
|
||||
if ingressPaths == nil {
|
||||
return []string{"/"}
|
||||
}
|
||||
paths := make([]string, len(rv.HTTP.Paths))
|
||||
for n, p := range rv.HTTP.Paths {
|
||||
path := p.Path
|
||||
if path == "" {
|
||||
paths := make([]string, len(ingressPaths))
|
||||
for n, p := range ingressPaths {
|
||||
path := p
|
||||
if p == "" {
|
||||
path = "/"
|
||||
}
|
||||
paths[n] = path
|
||||
|
@ -213,83 +187,31 @@ func pathsFromIngressRule(rv *v1.IngressRuleValue) []string {
|
|||
return paths
|
||||
}
|
||||
|
||||
func pathsFromIngressRuleV1beta1(rv *v1beta1.IngressRuleValue) []string {
|
||||
if rv.HTTP == nil {
|
||||
return []string{"/"}
|
||||
}
|
||||
paths := make([]string, len(rv.HTTP.Paths))
|
||||
for n, p := range rv.HTTP.Paths {
|
||||
path := p.Path
|
||||
if path == "" {
|
||||
path = "/"
|
||||
}
|
||||
paths[n] = path
|
||||
}
|
||||
return paths
|
||||
}
|
||||
|
||||
func (i *Ingress) buildIngress(ingress *v1.Ingress) *targetgroup.Group {
|
||||
func (i *Ingress) buildIngress(ingress ingressAdaptor) *targetgroup.Group {
|
||||
tg := &targetgroup.Group{
|
||||
Source: ingressSource(ingress),
|
||||
}
|
||||
tg.Labels = ingressLabels(ingress)
|
||||
|
||||
tlsHosts := make(map[string]struct{})
|
||||
for _, tls := range ingress.Spec.TLS {
|
||||
for _, host := range tls.Hosts {
|
||||
tlsHosts[host] = struct{}{}
|
||||
}
|
||||
for _, host := range ingress.tlsHosts() {
|
||||
tlsHosts[host] = struct{}{}
|
||||
}
|
||||
|
||||
for _, rule := range ingress.Spec.Rules {
|
||||
paths := pathsFromIngressRule(&rule.IngressRuleValue)
|
||||
for _, rule := range ingress.rules() {
|
||||
paths := pathsFromIngressPaths(rule.paths())
|
||||
|
||||
scheme := "http"
|
||||
_, isTLS := tlsHosts[rule.Host]
|
||||
_, isTLS := tlsHosts[rule.host()]
|
||||
if isTLS {
|
||||
scheme = "https"
|
||||
}
|
||||
|
||||
for _, path := range paths {
|
||||
tg.Targets = append(tg.Targets, model.LabelSet{
|
||||
model.AddressLabel: lv(rule.Host),
|
||||
model.AddressLabel: lv(rule.host()),
|
||||
ingressSchemeLabel: lv(scheme),
|
||||
ingressHostLabel: lv(rule.Host),
|
||||
ingressPathLabel: lv(path),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return tg
|
||||
}
|
||||
|
||||
func (i *Ingress) buildIngressV1beta1(ingress *v1beta1.Ingress) *targetgroup.Group {
|
||||
tg := &targetgroup.Group{
|
||||
Source: ingressSourceV1beta1(ingress),
|
||||
}
|
||||
tg.Labels = ingressLabelsV1beta1(ingress)
|
||||
|
||||
tlsHosts := make(map[string]struct{})
|
||||
for _, tls := range ingress.Spec.TLS {
|
||||
for _, host := range tls.Hosts {
|
||||
tlsHosts[host] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
for _, rule := range ingress.Spec.Rules {
|
||||
paths := pathsFromIngressRuleV1beta1(&rule.IngressRuleValue)
|
||||
|
||||
scheme := "http"
|
||||
_, isTLS := tlsHosts[rule.Host]
|
||||
if isTLS {
|
||||
scheme = "https"
|
||||
}
|
||||
|
||||
for _, path := range paths {
|
||||
tg.Targets = append(tg.Targets, model.LabelSet{
|
||||
model.AddressLabel: lv(rule.Host),
|
||||
ingressSchemeLabel: lv(scheme),
|
||||
ingressHostLabel: lv(rule.Host),
|
||||
ingressHostLabel: lv(rule.host()),
|
||||
ingressPathLabel: lv(path),
|
||||
})
|
||||
}
|
||||
|
|
145
discovery/kubernetes/ingress_adaptor.go
Normal file
145
discovery/kubernetes/ingress_adaptor.go
Normal file
|
@ -0,0 +1,145 @@
|
|||
// Copyright 2016 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package kubernetes
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/networking/v1"
|
||||
"k8s.io/api/networking/v1beta1"
|
||||
)
|
||||
|
||||
// ingressAdaptor is an adaptor for the different Ingress versions
|
||||
type ingressAdaptor interface {
|
||||
name() string
|
||||
namespace() string
|
||||
labels() map[string]string
|
||||
annotations() map[string]string
|
||||
tlsHosts() []string
|
||||
ingressClassName() *string
|
||||
rules() []ingressRuleAdaptor
|
||||
}
|
||||
|
||||
type ingressRuleAdaptor interface {
|
||||
paths() []string
|
||||
host() string
|
||||
}
|
||||
|
||||
// Adaptor for networking.k8s.io/v1
|
||||
type ingressAdaptorV1 struct {
|
||||
ingress *v1.Ingress
|
||||
}
|
||||
|
||||
func newIngressAdaptorFromV1(ingress *v1.Ingress) ingressAdaptor {
|
||||
return &ingressAdaptorV1{ingress: ingress}
|
||||
}
|
||||
|
||||
func (i *ingressAdaptorV1) name() string { return i.ingress.Name }
|
||||
func (i *ingressAdaptorV1) namespace() string { return i.ingress.Namespace }
|
||||
func (i *ingressAdaptorV1) labels() map[string]string { return i.ingress.Labels }
|
||||
func (i *ingressAdaptorV1) annotations() map[string]string { return i.ingress.Annotations }
|
||||
func (i *ingressAdaptorV1) ingressClassName() *string { return i.ingress.Spec.IngressClassName }
|
||||
|
||||
func (i *ingressAdaptorV1) tlsHosts() []string {
|
||||
var hosts []string
|
||||
for _, tls := range i.ingress.Spec.TLS {
|
||||
for _, host := range tls.Hosts {
|
||||
hosts = append(hosts, host)
|
||||
}
|
||||
}
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (i *ingressAdaptorV1) rules() []ingressRuleAdaptor {
|
||||
var rules []ingressRuleAdaptor
|
||||
for _, rule := range i.ingress.Spec.Rules {
|
||||
rules = append(rules, newIngressRuleAdaptorFromV1(rule))
|
||||
}
|
||||
return rules
|
||||
}
|
||||
|
||||
type ingressRuleAdaptorV1 struct {
|
||||
rule v1.IngressRule
|
||||
}
|
||||
|
||||
func newIngressRuleAdaptorFromV1(rule v1.IngressRule) ingressRuleAdaptor {
|
||||
return &ingressRuleAdaptorV1{rule: rule}
|
||||
}
|
||||
|
||||
func (i *ingressRuleAdaptorV1) paths() []string {
|
||||
rv := i.rule.IngressRuleValue
|
||||
if rv.HTTP == nil {
|
||||
return nil
|
||||
}
|
||||
paths := make([]string, len(rv.HTTP.Paths))
|
||||
for n, p := range rv.HTTP.Paths {
|
||||
paths[n] = p.Path
|
||||
}
|
||||
return paths
|
||||
}
|
||||
|
||||
func (i *ingressRuleAdaptorV1) host() string { return i.rule.Host }
|
||||
|
||||
// Adaptor for networking.k8s.io/v1beta1
|
||||
type ingressAdaptorV1Beta1 struct {
|
||||
ingress *v1beta1.Ingress
|
||||
}
|
||||
|
||||
func newIngressAdaptorFromV1beta1(ingress *v1beta1.Ingress) ingressAdaptor {
|
||||
return &ingressAdaptorV1Beta1{ingress: ingress}
|
||||
}
|
||||
|
||||
func (i *ingressAdaptorV1Beta1) name() string { return i.ingress.Name }
|
||||
func (i *ingressAdaptorV1Beta1) namespace() string { return i.ingress.Namespace }
|
||||
func (i *ingressAdaptorV1Beta1) labels() map[string]string { return i.ingress.Labels }
|
||||
func (i *ingressAdaptorV1Beta1) annotations() map[string]string { return i.ingress.Annotations }
|
||||
func (i *ingressAdaptorV1Beta1) ingressClassName() *string { return i.ingress.Spec.IngressClassName }
|
||||
|
||||
func (i *ingressAdaptorV1Beta1) tlsHosts() []string {
|
||||
var hosts []string
|
||||
for _, tls := range i.ingress.Spec.TLS {
|
||||
for _, host := range tls.Hosts {
|
||||
hosts = append(hosts, host)
|
||||
}
|
||||
}
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (i *ingressAdaptorV1Beta1) rules() []ingressRuleAdaptor {
|
||||
var rules []ingressRuleAdaptor
|
||||
for _, rule := range i.ingress.Spec.Rules {
|
||||
rules = append(rules, newIngressRuleAdaptorFromV1Beta1(rule))
|
||||
}
|
||||
return rules
|
||||
}
|
||||
|
||||
type ingressRuleAdaptorV1Beta1 struct {
|
||||
rule v1beta1.IngressRule
|
||||
}
|
||||
|
||||
func newIngressRuleAdaptorFromV1Beta1(rule v1beta1.IngressRule) ingressRuleAdaptor {
|
||||
return &ingressRuleAdaptorV1Beta1{rule: rule}
|
||||
}
|
||||
|
||||
func (i *ingressRuleAdaptorV1Beta1) paths() []string {
|
||||
rv := i.rule.IngressRuleValue
|
||||
if rv.HTTP == nil {
|
||||
return nil
|
||||
}
|
||||
paths := make([]string, len(rv.HTTP.Paths))
|
||||
for n, p := range rv.HTTP.Paths {
|
||||
paths[n] = p.Path
|
||||
}
|
||||
return paths
|
||||
}
|
||||
|
||||
func (i *ingressRuleAdaptorV1Beta1) host() string { return i.rule.Host }
|
Loading…
Reference in a new issue