forked from prymitive/karma
-
Notifications
You must be signed in to change notification settings - Fork 0
/
proxy.go
84 lines (72 loc) · 2.44 KB
/
proxy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package main
import (
"fmt"
"net/http"
"net/http/httputil"
"net/url"
"strings"
"github.com/gin-gonic/gin"
"github.com/prymitive/karma/internal/alertmanager"
"github.com/prymitive/karma/internal/config"
log "github.com/sirupsen/logrus"
)
func proxyPathPrefix(name string) string {
maybeSlash := ""
if !strings.HasSuffix(config.Config.Listen.Prefix, "/") {
maybeSlash = "/"
}
return fmt.Sprintf("%s%sproxy/alertmanager/%s", config.Config.Listen.Prefix, maybeSlash, name)
}
func proxyPath(name, path string) string {
return fmt.Sprintf("%s%s", proxyPathPrefix(name), path)
}
// NewAlertmanagerProxy creates a proxy instance for given alertmanager instance
func NewAlertmanagerProxy(alertmanager *alertmanager.Alertmanager) (*httputil.ReverseProxy, error) {
upstreamURL, err := url.Parse(alertmanager.URI)
if err != nil {
return nil, err
}
proxy := httputil.ReverseProxy{
Director: func(req *http.Request) {
req.URL.Scheme = upstreamURL.Scheme
req.URL.Host = upstreamURL.Host
if upstreamURL.User.Username() != "" {
username := upstreamURL.User.Username()
password, _ := upstreamURL.User.Password()
req.SetBasicAuth(username, password)
}
// drop Accept-Encoding header so we always get uncompressed reponses from
// upstream, there's a gzip middleware that's global so we don't want it
// to gzip twice
req.Header.Del("Accept-Encoding")
// set hostname of proxied target
req.Host = upstreamURL.Host
// Prepend with upstream URL path if exists
if len(upstreamURL.Path) > 0 {
req.URL.Path = strings.TrimSuffix(upstreamURL.Path, "/") + req.URL.Path
}
log.Debugf("[%s] Proxy request for %s", alertmanager.Name, req.URL.Path)
},
Transport: alertmanager.HTTPTransport,
ModifyResponse: func(resp *http.Response) error {
// drop Content-Length header from upstream responses, gzip middleware
// will compress those and that could cause a mismatch
resp.Header.Del("Content-Length")
return nil
},
}
return &proxy, nil
}
func setupRouterProxyHandlers(router *gin.Engine, alertmanager *alertmanager.Alertmanager) error {
proxy, err := NewAlertmanagerProxy(alertmanager)
if err != nil {
return err
}
router.POST(
proxyPath(alertmanager.Name, "/api/v1/silences"),
gin.WrapH(http.StripPrefix(proxyPathPrefix(alertmanager.Name), proxy)))
router.DELETE(
proxyPath(alertmanager.Name, "/api/v1/silence/*id"),
gin.WrapH(http.StripPrefix(proxyPathPrefix(alertmanager.Name), proxy)))
return nil
}