@@ -3,10 +3,10 @@ package handler
33import (
44 "fmt"
55 "strings"
6+ "sync"
67
78 "github.com/haproxytech/kubernetes-ingress/pkg/annotations"
89 "github.com/haproxytech/kubernetes-ingress/pkg/haproxy"
9- "github.com/haproxytech/kubernetes-ingress/pkg/haproxy/instance"
1010 k8ssync "github.com/haproxytech/kubernetes-ingress/pkg/k8s/sync"
1111 "github.com/haproxytech/kubernetes-ingress/pkg/store"
1212)
@@ -16,29 +16,69 @@ type PrometheusEndpoint struct {
1616 PodNs string
1717}
1818
19+ var (
20+ prometheusUsers map [string ]prometheusAuthUser
21+ prometheusUsersActive bool
22+ prometheusMu sync.RWMutex
23+ )
24+
1925//nolint:golint, stylecheck
2026const (
2127 PROMETHEUS_URL_PATH = "/metrics"
2228 PROMETHEUS_SERVICE_NAME = "prometheus"
2329)
2430
31+ type prometheusAuthUser struct {
32+ Password string
33+ Salt string
34+ }
35+
36+ func PrometheusAuthUsers () map [string ]prometheusAuthUser {
37+ prometheusMu .RLock ()
38+ defer prometheusMu .RUnlock ()
39+ users := make (map [string ]prometheusAuthUser , len (prometheusUsers ))
40+ for user , passwordData := range prometheusUsers {
41+ users [user ] = prometheusAuthUser {
42+ Password : passwordData .Password ,
43+ Salt : passwordData .Salt ,
44+ }
45+ }
46+ return users
47+ }
48+
49+ func PrometheusAuthActive () bool {
50+ prometheusMu .RLock ()
51+ defer prometheusMu .RUnlock ()
52+ return prometheusUsersActive
53+ }
54+
2555func (handler PrometheusEndpoint ) Update (k store.K8s , h haproxy.HAProxy , a annotations.Annotations ) (err error ) {
2656 if handler .PodNs == "" {
27- return
57+ return nil
2858 }
2959
30- prometheusSvcName := "prometheus"
31- prometheusBackendName := fmt .Sprintf ("%s_svc_%s_http" , handler .PodNs , PROMETHEUS_SERVICE_NAME )
32-
33- status := store .EMPTY
3460 var secret * store.Secret
35- _ , errBackend := h .BackendGet (prometheusBackendName )
36- backendExists := errBackend == nil
3761
3862 annSecret := annotations .String ("prometheus-endpoint-auth-secret" , k .ConfigMaps .Main .Annotations )
39- var secretExists , secretChanged , userListChanged bool
40- userListExists , _ := h .UserListExistsByGroup ("haproxy-controller-prometheus" )
63+ prometheusMu .RLock ()
64+ prometheusUsersActiveLocal := prometheusUsersActive
65+ prometheusMu .RUnlock ()
66+
67+ if annSecret != "" && ! prometheusUsersActiveLocal {
68+ prometheusMu .Lock ()
69+ prometheusUsersActive = true
70+ prometheusMu .Unlock ()
71+ } else if annSecret == "" && prometheusUsersActiveLocal {
72+ prometheusMu .Lock ()
73+ prometheusUsersActive = false
74+ prometheusUsers = nil
75+ prometheusMu .Unlock ()
76+ }
77+ if annSecret == "" {
78+ return nil
79+ }
4180
81+ var secretExists bool
4282 // Does the secret exist in store ? ...
4383 if annSecret != "" {
4484 secretFQN := strings .Split (annSecret , "/" )
@@ -47,87 +87,34 @@ func (handler PrometheusEndpoint) Update(k store.K8s, h haproxy.HAProxy, a annot
4787 if ns != nil {
4888 secret = ns .Secret [secretFQN [1 ]]
4989 secretExists = secret != nil && secret .Status != store .DELETED
50- secretChanged = secret .Status == store .MODIFIED
5190 }
5291 }
53- userListChanged = secretChanged || ! userListExists
54- } else {
55- userListChanged = userListExists
56- }
57-
58- if ! backendExists {
59- status = store .ADDED
60- }
61-
62- if ! userListChanged && status == store .EMPTY && (! secretExists || (secretExists && secret .Status == store .EMPTY )) {
63- return
64- }
65-
66- svc := & store.Service {
67- Namespace : handler .PodNs ,
68- Name : prometheusSvcName ,
69- Status : status ,
70- Annotations : k .ConfigMaps .Main .Annotations ,
71- Ports : []store.ServicePort {
72- {
73- Name : "http" ,
74- Protocol : "http" ,
75- Port : 8765 ,
76- Status : status ,
77- },
78- },
79- Faked : true ,
80- }
81- endpoints := & store.Endpoints {
82- Namespace : handler .PodNs ,
83- Service : prometheusSvcName ,
84- SliceName : prometheusSvcName ,
85- Status : status ,
86- Ports : map [string ]* store.PortEndpoints {
87- "http" : {
88- Port : int64 (h .Env .ControllerPort ),
89- Addresses : map [string ]struct {}{"127.0.0.1" : {}},
90- },
91- },
92- }
93-
94- if status != store .EMPTY {
95- k .EventService (k .GetNamespace (svc .Namespace ), svc )
96- k .EventEndpoints (k .GetNamespace (endpoints .Namespace ), endpoints , func (* store.RuntimeBackend , bool ) error { return nil })
97- }
98-
99- ing := & store.Ingress {
100- Status : status ,
101- Faked : true ,
102- IngressCore : store.IngressCore {
103- Namespace : handler .PodNs ,
104- Name : "prometheus" ,
105- Rules : map [string ]* store.IngressRule {"" : {
106- Paths : map [string ]* store.IngressPath {
107- PROMETHEUS_URL_PATH : {
108- SvcNamespace : svc .Namespace ,
109- SvcName : svc .Name ,
110- Path : PROMETHEUS_URL_PATH ,
111- SvcPortString : "http" ,
112- PathTypeMatch : store .PATH_TYPE_IMPLEMENTATION_SPECIFIC ,
113- },
114- },
115- }},
116- },
11792 }
11893
11994 if secretExists {
120- ing .Annotations = map [string ]string {
121- "auth-type" : "basic-auth" ,
122- "auth-secret" : annSecret ,
95+ // first see if we need to do something
96+ prometheusMu .RLock ()
97+ // prometheusUsers != nil, not len, there is a diff in logic
98+ if secret .Status == store .EMPTY && prometheusUsers != nil {
99+ prometheusMu .RUnlock ()
100+ return nil
123101 }
102+ prometheusMu .RUnlock ()
103+
104+ // then fill users if needed
105+ prometheusMu .Lock ()
106+ prometheusUsers = make (map [string ]prometheusAuthUser )
107+ for user , password := range secret .Data {
108+ partsPass := strings .Split (string (password ), "$" )
109+ salt := fmt .Sprintf ("$%s$%s$" , partsPass [1 ], partsPass [2 ])
110+ prometheusUsers [user ] = prometheusAuthUser {
111+ Password : string (password ),
112+ Salt : salt ,
113+ }
114+ logger .Debugf ("Adding prometheus user '%s' from secret '%s'" , user , annSecret )
115+ }
116+ prometheusUsersActive = true
117+ prometheusMu .Unlock ()
124118 }
125-
126- if userListChanged || status != store .EMPTY || secretExists && secret .Status != store .EMPTY {
127- k .EventIngress (k .GetNamespace (ing .Namespace ), ing , "fakeUID" , "fakeResourceVersion" )
128- }
129-
130- instance .ReloadIf (status != store .EMPTY , "creation/modification of prometheus endpoint" )
131-
132119 return nil
133120}
0 commit comments