Compare commits

...

15 Commits

Author SHA1 Message Date
60ab4ff110 Migration to kubernetes + vault-agent 2025-01-13 17:00:23 +01:00
4219a7d001 update README 2023-07-19 16:56:26 +02:00
7ffefb1159 Moving to kube, refactoring code, using env variables only, adding metrics exporter 2023-07-19 16:47:23 +02:00
b64d359c27 Refactoring project, adding BAN handling with X-Cache-Tags 2023-05-25 10:53:55 +02:00
b94c8800b0 Cleaning README, adding systemd service file 2023-05-12 10:35:59 +02:00
Sebastien Laithier
85b0cffdad Improve logging 2023-05-11 17:07:36 +02:00
Sebastien Laithier
17579b6f0b Merge branch 'main' of gitlab.infolegale.net:infrastructure/http-broadcaster into main 2023-05-11 15:32:10 +02:00
Sebastien Laithier
923952e8f6 Update README, clearing error log messages 2023-05-11 15:32:07 +02:00
Sebastien Laithier
35638213c5 Update README.md 2023-05-11 12:18:24 +02:00
Sebastien Laithier
5779e2c39e update README 2023-05-11 12:15:09 +02:00
Sebastien Laithier
ddb30a3a5a adding missing log dir 2023-05-11 12:00:19 +02:00
Sebastien Laithier
f6173a09b2 Adding proper logging file, cleaning main.go, gitignore update 2023-05-11 11:53:27 +02:00
Sebastien Laithier
f3be636af4 Gitignore 2023-05-10 16:39:55 +02:00
Sebastien Laithier
73a92f6dd9 update CI 2023-05-10 16:15:21 +02:00
Sebastien Laithier
0d2eaa3c09 update CI 2023-05-10 16:14:20 +02:00
17 changed files with 622 additions and 214 deletions

8
.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
.idea/*
*.swp
*.log
varnish_list
helm/charts/*
Chart.lock
app/*.log
app/http-broadcaster

View File

@@ -6,6 +6,7 @@ linter:
stage: lint stage: lint
image: cytopia/golint:latest image: cytopia/golint:latest
script: script:
- cd app/
- golint main.go - golint main.go
compile: compile:
@@ -15,7 +16,7 @@ compile:
- cd app/ - cd app/
- go get ./... - go get ./...
- CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o ../build/http-broadcaster main.go - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o ../build/http-broadcaster main.go
- cp -r ../build/ - cp -r log/ ../build/
artifacts: artifacts:
paths: paths:
- build/ - build/

61
Dockerfile Normal file
View File

@@ -0,0 +1,61 @@
########################
# BASE
########################
FROM golang:1.23.3-alpine as base
ENV CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64
ARG APP_UID=1000
ARG APP_GID=1000
RUN addgroup -S app -g ${APP_GID} && adduser -u ${APP_UID} -S -D -G app app
RUN apk update \
&& apk add --no-cache bash ca-certificates tzdata curl \
&& update-ca-certificates
ENV TZ="Europe/Paris"
COPY ./app /app
WORKDIR /app
COPY ./docker/config/env.local /vault/secrets/.env
RUN go mod download && go mod verify
########################
# BUILD
########################
FROM base as build-env
RUN go build -ldflags="-w -s" -o /http-broadcaster
########################
# PROD ENV ###
########################
FROM alpine:3.20 as prod
ARG APP_UID=1000
ARG APP_GID=1000
RUN addgroup -S app -g ${APP_GID} && adduser -u ${APP_UID} -S -D -G app app
RUN apk update \
&& apk add --no-cache bash ca-certificates tzdata curl \
&& update-ca-certificates
ENV TZ="Europe/Paris"
COPY --from=build-env /http-broadcaster /usr/local/bin/http-broadcaster
RUN chmod +x /usr/local/bin/http-broadcaster
RUN mkdir /app && chown ${APP_UID}:${APP_GID} /app
USER app
########################
# DEV
########################
FROM base as dev
COPY --from=build-env /http-broadcaster /usr/local/bin/http-broadcaster
RUN chmod +x /usr/local/bin/http-broadcaster
ENTRYPOINT ["http-broadcaster"]

111
README.md
View File

@@ -1,92 +1,35 @@
# http-broadcaster # http-broadcaster
## Getting started
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
## Add your files
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
```
cd existing_repo
git remote add origin https://gitlab.infolegale.net/infrastructure/http-broadcaster.git
git branch -M main
git push -uf origin main
```
## Integrate with your tools
- [ ] [Set up project integrations](https://gitlab.infolegale.net/infrastructure/http-broadcaster/-/settings/integrations)
## Collaborate with your team
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
## Test and Deploy
Use the built-in continuous integration in GitLab.
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
***
# Editing this README
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template.
## Suggestions for a good README
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
## Name
Choose a self-explaining name for your project.
## Description ## Description
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. Un démon simple écrit en Go qui prend une requête PURGE en entrée et la transmet à plusieurs serveurs varnish.
## Badges ## Déploiement
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. Le projet se déploie via les pipelines Gitlab en stg et en prod, via un déclenchement manuel.
Le sidecar vault va déposer un fichier (/vault/secrets/.env) contenant les variables d'environnements.
## Visuals ## Configuration
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. Arguments de lancement :
* -l (--log) : emplacement du fichier de log. (Default : /app/http-broadcaster.log)
* -e (--envfile) : emplacement du fichier de variables d'environnement. (Default : /vault/secrets/.env)
* --metrics : active l'exposition des métriques prometheus sur /metrics. (Default : false)
## Installation ### Variables d'environement
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
La liste de serveurs Varnish peut être fournie directement dans un fichier d'env :
* VARNISH_SERVERS: list of varnish backend servers. Ex "http://10.13.32.1:6081,http://10.13.32.2:6081"
* CLIENT_LIST : list of IPs in CIDR format (0.0.0.0/32) of authorized client to do purge/ban requests.
## Fonctionnalites
* Génère la liste des serveurs Varnish à partir des variables d'environnement.
* Ecoute sur le port 6081.
* Healthcheck disponible sur l'uri /healthcheck pour vérifier son bon fonctionnement. Renvoie un code HTTP 200 et le message "OK".
* Metriques Prometheus disponible (désactivée par défaut).
* Traite les requêtes entrantes en récupérant 3 éléments et en les intégrant à la requête transmise aux serveurs Varnish :
- La méthode (PURGE ou BAN par exemple)
- L'url : / pour BAN, /codes/api/greffes/0101 par exemple pour PURGE.
- Le header X-Cache-Tags : dans le cas d'un BAN ce header contient une valeur.
## Usage ## Usage
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. Les interactions se font via le protocol HTTP. Les applications où les utilisateurs envoient une requête de méthode PURGE vers le démon.
Une fois le traitement d'une requête effectuée, le démon renvoie 200 si tout est ok, 405 dans le cas contraire.
## Support
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
## Roadmap
If you have ideas for releases in the future, it is a good idea to list them in the README.
## Contributing
State if you are open to contributions and what your requirements are for accepting them.
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
## Authors and acknowledgment
Show your appreciation to those who have contributed to the project.
## License
For open source projects, say how it is licensed.
## Project status
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.

2
app/.env.example Normal file
View File

@@ -0,0 +1,2 @@
CLIENT_LIST="127.0.0.1/32"
VARNISH_SERVERS="127.0.0.1:6081"

114
app/Http/utils.go Normal file
View File

@@ -0,0 +1,114 @@
// Package http provides functions to handle incoming HTTP requests
package http
import (
prometheus "http-broadcaster/Prometheus"
tools "http-broadcaster/Tools"
varnish "http-broadcaster/Varnish"
"io"
"log"
"net/http"
"strconv"
"strings"
"time"
)
// logRequest print the requests and wanted informations in log file
func logRequest(t time.Time, r *http.Request, s int, h map[string]string) {
// Test if X-Cache-Tags header is empty
if len(h) == 0 {
log.Printf("%s %s - - %s \"%s %s %s\" %d 0 \"-\" \"%s\" %d\n",
r.Host,
r.Header["X-Forwarded-For"][0],
t.Format("[02/Jan/2006:15:04:05 -0700]"),
r.Method,
r.URL.Path,
r.Proto,
s,
r.UserAgent(),
time.Since(t).Milliseconds(),
)
} else {
var header string
if h["X-Cache-Tags"] != "" {
header = h["X-Cache-Tags"]
} else {
header = h["ApiPlatform-Ban-Regex"]
}
log.Printf("%s %s - - %s \"%s %s %s\" %d 0 \"-\" \"%s\" %d %s\n",
r.Host,
r.Header["X-Forwarded-For"][0],
t.Format("[02/Jan/2006:15:04:05 -0700]"),
r.Method,
r.URL.Path,
r.Proto,
s,
r.UserAgent(),
time.Since(t).Milliseconds(),
header,
)
}
}
// checkAllowedIP verify if the IPs is authorized to do BAN/PURGE request.
func checkAllowedIP(ip string) bool {
return tools.IPAllowed(ip)
}
// RequestHandler handles requests to broadcast to all varnish instances.
func RequestHandler(w http.ResponseWriter, r *http.Request) {
var tag = make(map[string]string)
ipAddress := r.RemoteAddr
// check x-forwarded-for instead of RemoteAddr header because kube
//ip, err := netip.ParseAddr(r.Header["X-Forwarded-For"][0])
fwdAddress := r.Header.Get("X-Forwarded-For")
if fwdAddress != "" {
// Case there is a single IP in the header
ipAddress = fwdAddress
ips := strings.Split(fwdAddress, ",")
if len(ips) > 1 {
ipAddress = ips[0]
}
}
// If IP is not authorized to do purge/ban requests, respond with 401.
if !checkAllowedIP(ipAddress) {
log.Printf("Client ip not authorized : %v", ipAddress)
w.WriteHeader(401)
_, _ = io.WriteString(w, strconv.Itoa(401))
return
}
// If metrics are not enabled, return 404 on /metrics path.
if r.URL.Path == "/metrics" && !prometheus.MetricsEnabled {
w.WriteHeader(404)
_, _ = io.WriteString(w, strconv.Itoa(404))
return
}
t := time.Now()
url := r.URL.String()
method := r.Method
h := r.Header.Get("X-Cache-Tags")
if h != "" {
tag["X-Cache-Tags"] = h
}
h = r.Header.Get("ApiPlatform-Ban-Regex")
if h != "" {
tag["ApiPlatform-Ban-Regex"] = h
}
status := varnish.SendToVarnish(method, url, tag)
if prometheus.MetricsEnabled {
prometheus.IncrementClientCounterVec(method)
}
// Return HTTP code 405 if not all varnish servers returned 200.
if status != 200 {
w.WriteHeader(405)
}
logRequest(t, r, status, tag)
_, _ = io.WriteString(w, strconv.Itoa(status))
}
// HealthHandler handles healthcheck requests and return 200.
func HealthHandler(w http.ResponseWriter, _ *http.Request) {
_, _ = io.WriteString(w, "OK")
}

76
app/Prometheus/utils.go Normal file
View File

@@ -0,0 +1,76 @@
// Package prometheus provides useful functions to initialize and populate metrics
package prometheus
import (
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/collectors"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// Metrics structure for storing counter
type Metrics struct {
ClientHTTPReqs *prometheus.CounterVec
BackendHTTPReqs *prometheus.CounterVec
}
var (
// HTTPCounter Metrics
HTTPCounter = initializeHTTPReqCounter()
// Reg is a custom registry to have more control on metrics exported.
Reg = prometheus.NewRegistry()
// MetricsEnabled is the flag used to enable the prometheus metrics backend.
MetricsEnabled = false
)
// InitMetrics enable the metrics functionality if the flags is passed as an argument
func InitMetrics(m bool) {
if m {
MetricsEnabled = true
initPrometheusRegistry()
// Define custom promhttp handler that expose just our custom registry.
http.Handle("/metrics", promhttp.HandlerFor(Reg, promhttp.HandlerOpts{
EnableOpenMetrics: true,
Registry: Reg,
}))
}
}
// InitPrometheusRegistry initialize registry and counters if metrics flag pass as argument.
func initPrometheusRegistry() {
// We use a custom registry to better now what metrics are exposed.
Reg = prometheus.NewRegistry()
Reg.MustRegister(HTTPCounter.ClientHTTPReqs)
Reg.MustRegister(HTTPCounter.BackendHTTPReqs)
Reg.MustRegister(collectors.NewBuildInfoCollector())
}
// IncrementClientCounterVec increments the counter with method label provided.
func IncrementClientCounterVec(m string) {
HTTPCounter.ClientHTTPReqs.WithLabelValues(m).Inc()
}
// IncrementBackendCounterVec increments the counter with method label provided.
func IncrementBackendCounterVec(m string) {
HTTPCounter.BackendHTTPReqs.WithLabelValues(m).Inc()
}
// InitializeHTTPReqCounter inits the httpReqs counter that will be exported.
func initializeHTTPReqCounter() *Metrics {
HTTPCounters := &Metrics{
ClientHTTPReqs: prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "client_http_requests_total",
Help: "How many HTTP requests processed, partitioned by HTTP method.",
},
[]string{"method"},
),
BackendHTTPReqs: prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "backend_http_requests_total",
Help: "How many HTTP requests sent to backend, partitioned by HTTP method.",
},
[]string{"method"},
),
}
return HTTPCounters
}

64
app/Tools/utils.go Normal file
View File

@@ -0,0 +1,64 @@
package Tools
import (
"log"
"net/netip"
"os"
"strings"
"github.com/joho/godotenv"
)
var (
// ClientList contains IPs/networks authorized to do purge/ban
ClientList []netip.Prefix
)
// ReadDotEnvFile reads environment variables from .env file
func ReadDotEnvFile(f string) {
err := godotenv.Load(f)
if err != nil {
log.Fatal("Error loading .env file")
}
}
// InitLog ensure log file exists and set appropriate flags (remove timestamp at start of line).
func InitLog(p string) {
logFile, err := os.OpenFile(p, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
panic(err)
}
log.SetOutput(logFile)
log.SetFlags(log.Flags() &^ (log.Ldate | log.Ltime))
}
// InitAllowedIPList initialize the list of client authorized to do purge/ban requests
func InitAllowedIPList(l string) []netip.Prefix {
list := []netip.Prefix{}
if l != "" {
sliceData := strings.Split(l, ",")
for i := 0; i < len(sliceData); i++ {
t, err := netip.ParsePrefix(sliceData[i])
if err != nil {
panic(err)
}
list = append(list, t)
}
return list
}
return list
}
// IPAllowed check if the IP is authorized to do BAN/PURGE requests
func IPAllowed(ip string) bool {
ipAddr, err := netip.ParseAddr(ip)
if err != nil {
log.Printf("Ip address wrong format %s", err)
}
for i := 0; i < len(ClientList); i++ {
if ClientList[i].Contains(ipAddr) {
return true
}
}
return false
}

64
app/Varnish/utils.go Normal file
View File

@@ -0,0 +1,64 @@
// Package varnish provides functions to build the list of varnish servers that will be used
package varnish
import (
prometheus2 "http-broadcaster/Prometheus"
"log"
"net/http"
"os"
"strings"
"time"
)
var (
// VarnishList contains the list of varnish servers.
VarnishList []string
status = 200
)
// InitializeVarnishList sets varnishList variable according to the LIST_METHOD env var
func InitializeVarnishList(l string) []string {
data := os.Getenv("VARNISH_SERVERS")
sliceData := strings.Split(string(data), ",")
return sliceData
}
// SendToVarnish send to all varnish servers define in varnishList the request with the PURGE or BAN method
// and the X-Cache-Tags header if necessary.
func SendToVarnish(method string, url string, tag map[string]string) int {
status = 200
// Take url to ban as argument.
// Loop over the list of Varnish servers and send PURGE request to each.
// Update status variable to check if servers have successfully purge url.
for i := 0; i < len(VarnishList); i++ {
client := &http.Client{
Timeout: 10 * time.Second,
}
// sanitize varnish server host.
domain := strings.Trim(VarnishList[i], "\r\n")
req, err := http.NewRequest(method, domain+url, nil)
if err != nil {
log.Println("Create new request : ", err)
}
// If X-Cache-Tags header is not empty with pass it to varnish.
if tag["X-Cache-Tags"] != "" {
req.Header.Add("X-Cache-Tags", tag["X-Cache-Tags"])
}
if tag["ApiPlatform-Ban-Regex"] != "" {
req.Header.Add("ApiPlatform-Ban-Regex", tag["ApiPlatform-Ban-Regex"])
}
resp, err := client.Do(req)
if err != nil {
log.Println("Send new request : ", err)
}
if prometheus2.MetricsEnabled {
prometheus2.IncrementBackendCounterVec(method)
}
if resp.StatusCode != 200 {
status = 405
}
resp.Body.Close()
}
return status
}

View File

@@ -1,61 +0,0 @@
package Vault
import (
"fmt"
"os"
vault "github.com/hashicorp/vault/api"
auth "github.com/hashicorp/vault/api/auth/approle"
)
// getVarnishList retrieve the list of varnish servers to send PURGE to.
// It uses the AppRole authentication method.
func getVarnishList() (string, error) {
config := vault.DefaultConfig() // modify for more granular configuration
client, err := vault.NewClient(config)
if err != nil {
return "", fmt.Errorf("unable to initialize Vault client: %w", err)
}
// Get roleID and secretID from ENV vars
roleID := os.Getenv("APPROLE_ROLE_ID")
if roleID == "" {
return "", fmt.Errorf("no role ID was provided in APPROLE_ROLE_ID env var")
}
secretID := os.Getenv("APPROLE_SECRET_ID")
if secretID == "" {
return "", fmt.Errorf("no secret ID was provided in APPROLE_SECRET_ID env var")
}
appRoleAuth, err := auth.NewAppRoleAuth(
roleID,
secretID,
auth.WithWrappingToken(), // Only required if the secret ID is response-wrapped.
)
if err != nil {
return "", fmt.Errorf("unable to initialize AppRole auth method: %w", err)
}
authInfo, err := client.Auth().Login(context.Background(), appRoleAuth)
if err != nil {
return "", fmt.Errorf("unable to login to AppRole auth method: %w", err)
}
if authInfo == nil {
return "", fmt.Errorf("no auth info was returned after login")
}
// get secret from the default mount path for KV v2 in dev mode, "secret"
secret, err := client.KVv2("app").Get(context.Background(), "http-broadcaster/stg/varnish_list")
if err != nil {
return "", fmt.Errorf("unable to read secret: %w", err)
}
// data map can contain more than one key-value pair,
// in this case we're just grabbing one of them
value, ok := secret.Data["list"].(string)
if !ok {
return "", fmt.Errorf("value type assertion failed: %T %#v", secret.Data["list"], secret.Data["list"])
}
return value, nil
}

View File

@@ -1,3 +1,25 @@
module http-broadcaster module http-broadcaster
go 1.13 go 1.20
require (
github.com/alexflint/go-arg v1.5.1
github.com/joho/godotenv v1.5.1
github.com/prometheus/client_golang v1.20.5
)
require (
github.com/alexflint/go-scalar v1.2.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
golang.org/x/sys v0.22.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
)

138
app/go.sum Normal file
View File

@@ -0,0 +1,138 @@
github.com/alecthomas/kingpin/v2 v2.3.1 h1:ANLJcKmQm4nIaog7xdr/id6FM6zm5hHnfZrvtKPxqGg=
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc=
github.com/alexflint/go-arg v1.4.3 h1:9rwwEBpMXfKQKceuZfYcwuc/7YY7tWJbFsgG5cAU/uo=
github.com/alexflint/go-arg v1.4.3/go.mod h1:3PZ/wp/8HuqRZMUUgu7I+e1qcpUbvmS258mRXkFH4IA=
github.com/alexflint/go-arg v1.5.0 h1:rwMKGiaQuRbXfZNyRUvIfke63QvOBt1/QTshlGQHohM=
github.com/alexflint/go-arg v1.5.0/go.mod h1:A7vTJzvjoaSTypg4biM5uYNTkJ27SkNTArtYXnlqVO8=
github.com/alexflint/go-arg v1.5.1 h1:nBuWUCpuRy0snAG+uIJ6N0UvYxpxA0/ghA/AaHxlT8Y=
github.com/alexflint/go-arg v1.5.1/go.mod h1:A7vTJzvjoaSTypg4biM5uYNTkJ27SkNTArtYXnlqVO8=
github.com/alexflint/go-scalar v1.1.0 h1:aaAouLLzI9TChcPXotr6gUhq+Scr8rl0P9P4PnltbhM=
github.com/alexflint/go-scalar v1.1.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o=
github.com/alexflint/go-scalar v1.2.0 h1:WR7JPKkeNpnYIOfHRa7ivM21aWAdHD0gEWHCx+WQBRw=
github.com/alexflint/go-scalar v1.2.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q=
github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY=
github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk=
github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA=
github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU=
github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k=
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI=
github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_golang v1.20.2 h1:5ctymQzZlyOON1666svgwn3s6IKWgfbjsejTMiXIyjg=
github.com/prometheus/client_golang v1.20.2/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4=
github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=
github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 h1:v7DLqVdK4VrYkVD5diGdl4sxJurKJEMnODWRJlxV9oM=
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM=
github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY=
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI=
github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/xhit/go-str2duration v1.2.0 h1:BcV5u025cITWxEQKGWr1URRzrcXtu7uk8+luz3Yuhwc=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

0
app/log/.gitkeep Normal file
View File

View File

@@ -1,77 +1,35 @@
// Receive http PURGE request and broadcast it to several Varnish servers.
package main package main
import ( import (
"fmt" h "http-broadcaster/Http"
"io" prometheus2 "http-broadcaster/Prometheus"
tools "http-broadcaster/Tools"
varnish "http-broadcaster/Varnish"
"log" "log"
"net/http" "net/http"
"os" "os"
"strings"
)
const ( "github.com/alexflint/go-arg"
// MethodPurge declaration for Varnish.
MethodPurge = "PURGE"
) )
var ( var (
varnishList = MakeVarnishList() args struct {
status = "200 Purged" Log string `arg:"-l,--logfile" help:"location of output logfile." default:"/app/http-broadcaster.log"`
EnvFile string `arg:"-e,--envfile" help:"location of file containing environment variables." default:"/vault/secrets/.env"`
Metrics bool `arg:"--metrics" help:"enable prometheus exporter on /metrics." default:"false"`
}
) )
// MakeVarnishList reads the list of varnish servers from a file on disk.
func MakeVarnishList() []string {
Data, err := os.ReadFile("./varnish")
if err != nil {
log.Fatal(err)
}
sliceData := strings.Split(string(Data), ",")
return sliceData
}
// PurgeHandler handles PURGE request to broadcast it to all varnish instances.
func PurgeHandler(w http.ResponseWriter, r *http.Request) {
url := r.URL.String()
status := SendToVarnish(url)
if status != "200 Purged" {
w.WriteHeader(405)
}
io.WriteString(w, status)
}
// SendToVarnish send to all varnish servers define in varnishList the PURGE request.
func SendToVarnish(url string) string {
status = "200 Purged"
// Take url to ban as argument.
// Loop over the list of Varnish servers and send PURGE request to each.
for i := 0; i < len(varnishList); i++ {
//status = "200 Purged"
client := &http.Client{}
domain := strings.Trim(varnishList[i], "\r\n")
req, err := http.NewRequest(MethodPurge, domain + url, nil)
if err != nil {
log.Fatal("NewRequest: %s", err)
}
resp, err := client.Do(req)
if err != nil {
log.Fatal("Client.do: %s", err)
}
//fmt.Printf("Resp: %v\n", resp)
if resp.StatusCode != 200 {
status = "405 Not Allowed"
}
fmt.Println("Purge URL" + " " + domain + url + " : " + status)
}
return status
}
// HealthHandler handles healthcheck requests and return 200.
func HealthHandler(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "OK")
}
func main() { func main() {
http.HandleFunc("/", PurgeHandler) arg.MustParse(&args)
http.HandleFunc("/healthcheck", HealthHandler) tools.InitLog(args.Log)
log.Fatal(http.ListenAndServe(":6081",nil)) tools.ReadDotEnvFile(args.EnvFile)
tools.ClientList = tools.InitAllowedIPList(os.Getenv("CLIENT_LIST"))
varnish.VarnishList = varnish.InitializeVarnishList(os.Getenv("VARNISH_SERVERS"))
prometheus2.InitMetrics(args.Metrics)
http.HandleFunc("/", h.RequestHandler)
http.HandleFunc("/healthcheck", h.HealthHandler)
log.Fatal(http.ListenAndServe(":6081", nil))
} }

View File

@@ -1 +0,0 @@
http://10.13.32.1:6081,http://10.13.32.2:6081

18
docker-compose.yml Normal file
View File

@@ -0,0 +1,18 @@
---
version: '0.1'
services:
broadcaster:
container_name: httpbroadcaster
build:
context: ./
target: dev
ports:
- "6081:6081"
volumes:
- ./app/:/app/
networks:
- http-broadcaster
networks:
http-broadcaster:
driver: bridge

1
docker/config/env.local Normal file
View File

@@ -0,0 +1 @@
VARNISH_SERVERS="http://192.168.1.2:6081,http://192.168.1.1:6081"