Public source validation / validate (push) Failing after 3m8s
114 lines
4.1 KiB
Go
114 lines
4.1 KiB
Go
// Command integrationfixture is an isolated, deterministic external boundary
|
|
// used only by the real-stack smoke gate. It behaves as a Prometheus-compatible
|
|
// source and a webhook receiver; production images never include it.
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type counters struct {
|
|
mu sync.Mutex
|
|
prometheusRequests int
|
|
webhookRequests int
|
|
keys map[string]struct{}
|
|
lastEvent string
|
|
events map[string]int
|
|
}
|
|
|
|
func main() {
|
|
if len(os.Args) == 3 && (os.Args[1] == "health" || os.Args[1] == "get") {
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
defer cancel()
|
|
request, _ := http.NewRequestWithContext(ctx, http.MethodGet, os.Args[2], nil)
|
|
response, err := http.DefaultClient.Do(request)
|
|
if err != nil || response.StatusCode != http.StatusOK {
|
|
os.Exit(1)
|
|
}
|
|
defer response.Body.Close()
|
|
if os.Args[1] == "get" {
|
|
_, _ = io.CopyN(os.Stdout, response.Body, 64<<10)
|
|
}
|
|
return
|
|
}
|
|
listen := flag.String("listen", ":9090", "listen address")
|
|
flag.Parse()
|
|
state := &counters{keys: map[string]struct{}{}, events: map[string]int{}}
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("/healthz", func(writer http.ResponseWriter, _ *http.Request) { writer.WriteHeader(http.StatusOK) })
|
|
mux.HandleFunc("/api/v1/query", state.prometheus)
|
|
mux.HandleFunc("/api/v1/query_range", state.prometheus)
|
|
mux.HandleFunc("/webhook", state.webhook)
|
|
mux.HandleFunc("/smoke/status", state.status)
|
|
server := &http.Server{Addr: *listen, Handler: mux, ReadHeaderTimeout: 2 * time.Second, ReadTimeout: 5 * time.Second, WriteTimeout: 5 * time.Second, IdleTimeout: 15 * time.Second}
|
|
if err := server.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func (state *counters) prometheus(writer http.ResponseWriter, request *http.Request) {
|
|
if request.Method != http.MethodGet || strings.TrimSpace(request.URL.Query().Get("query")) == "" {
|
|
http.Error(writer, "invalid query", http.StatusBadRequest)
|
|
return
|
|
}
|
|
state.mu.Lock()
|
|
state.prometheusRequests++
|
|
state.mu.Unlock()
|
|
now := float64(time.Now().UTC().Unix())
|
|
data := map[string]any{"resultType": "vector", "result": []any{map[string]any{"metric": map[string]string{"instance": "smoke-host"}, "value": []any{now, "95"}}}}
|
|
if request.URL.Path == "/api/v1/query_range" {
|
|
data = map[string]any{"resultType": "matrix", "result": []any{map[string]any{"metric": map[string]string{"instance": "smoke-host"}, "values": []any{[]any{now - 60, "90"}, []any{now, "95"}}}}}
|
|
}
|
|
writeJSON(writer, http.StatusOK, map[string]any{"status": "success", "data": data})
|
|
}
|
|
|
|
func (state *counters) webhook(writer http.ResponseWriter, request *http.Request) {
|
|
if request.Method != http.MethodPost {
|
|
writer.WriteHeader(http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
expected := os.Getenv("PULSE_SMOKE_WEBHOOK_TOKEN")
|
|
if expected == "" || request.Header.Get("Authorization") != "Bearer "+expected {
|
|
writer.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
key := request.Header.Get("Idempotency-Key")
|
|
var payload struct {
|
|
EventType string `json:"eventType"`
|
|
}
|
|
if key == "" || json.NewDecoder(http.MaxBytesReader(writer, request.Body, 16<<10)).Decode(&payload) != nil {
|
|
writer.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
state.mu.Lock()
|
|
state.webhookRequests++
|
|
state.keys[key] = struct{}{}
|
|
state.lastEvent = payload.EventType
|
|
state.events[payload.EventType]++
|
|
state.mu.Unlock()
|
|
writer.WriteHeader(http.StatusNoContent)
|
|
}
|
|
|
|
func (state *counters) status(writer http.ResponseWriter, _ *http.Request) {
|
|
state.mu.Lock()
|
|
defer state.mu.Unlock()
|
|
writeJSON(writer, http.StatusOK, map[string]any{"prometheusRequests": state.prometheusRequests, "webhookRequests": state.webhookRequests, "uniqueDeliveryKeys": len(state.keys), "lastEventType": state.lastEvent, "events": state.events})
|
|
}
|
|
|
|
func writeJSON(writer http.ResponseWriter, status int, value any) {
|
|
writer.Header().Set("Content-Type", "application/json")
|
|
writer.WriteHeader(status)
|
|
_ = json.NewEncoder(writer).Encode(value)
|
|
}
|