82 lines
3.0 KiB
Go
82 lines
3.0 KiB
Go
package main
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"encoding/json"
|
||
|
|
"flag"
|
||
|
|
"fmt"
|
||
|
|
"os"
|
||
|
|
"path/filepath"
|
||
|
|
"strings"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"data-terminal-cloud/internal/alertreceiverconformance"
|
||
|
|
)
|
||
|
|
|
||
|
|
func main() {
|
||
|
|
routesPath := flag.String("routes", "", "GET /api/v1/ops/alert-routing-policies JSON")
|
||
|
|
testsPath := flag.String("tests", "", "GET /api/v1/ops/alert-delivery-tests JSON")
|
||
|
|
incidentPath := flag.String("incident", "", "GET /api/v1/ops/alerts/{id} formal drill JSON")
|
||
|
|
receiverPath := flag.String("receiver", "", "alert-receiver-capture-v1 JSON")
|
||
|
|
candidateVersion := flag.String("candidate-version", "", "release candidate version")
|
||
|
|
buildDigest := flag.String("build-digest", "", "sha256 immutable build digest")
|
||
|
|
outputPath := flag.String("output", "", "absolute output report path")
|
||
|
|
flag.Parse()
|
||
|
|
if *routesPath == "" || *testsPath == "" || *incidentPath == "" || *receiverPath == "" || strings.TrimSpace(*candidateVersion) == "" || strings.TrimSpace(*buildDigest) == "" || !filepath.IsAbs(*outputPath) {
|
||
|
|
fmt.Fprintln(os.Stderr, "usage: alert-receiver-conformance -routes routes.json -tests tests.json -incident incident.json -receiver receiver.json -candidate-version VERSION -build-digest sha256:... -output ABSOLUTE.json")
|
||
|
|
os.Exit(2)
|
||
|
|
}
|
||
|
|
routesContent, testsContent, incidentContent, receiverContent, err := readInputs(*routesPath, *testsPath, *incidentPath, *receiverPath)
|
||
|
|
if err != nil {
|
||
|
|
fmt.Fprintln(os.Stderr, err)
|
||
|
|
os.Exit(2)
|
||
|
|
}
|
||
|
|
routes, err := alertreceiverconformance.ParseRoutes(routesContent)
|
||
|
|
if err != nil {
|
||
|
|
failInput(err)
|
||
|
|
}
|
||
|
|
tests, err := alertreceiverconformance.ParseTests(testsContent)
|
||
|
|
if err != nil {
|
||
|
|
failInput(err)
|
||
|
|
}
|
||
|
|
incident, err := alertreceiverconformance.ParseIncident(incidentContent)
|
||
|
|
if err != nil {
|
||
|
|
failInput(err)
|
||
|
|
}
|
||
|
|
capture, err := alertreceiverconformance.ParseCapture(receiverContent)
|
||
|
|
if err != nil {
|
||
|
|
failInput(err)
|
||
|
|
}
|
||
|
|
report := alertreceiverconformance.Evaluate(routes, tests, incident, capture, *candidateVersion, *buildDigest, time.Now().UTC())
|
||
|
|
report.InputSHA256 = map[string]string{
|
||
|
|
"cloud_routes": alertreceiverconformance.SHA256(routesContent), "cloud_tests": alertreceiverconformance.SHA256(testsContent),
|
||
|
|
"cloud_incident": alertreceiverconformance.SHA256(incidentContent), "receiver_capture": alertreceiverconformance.SHA256(receiverContent),
|
||
|
|
}
|
||
|
|
encoded, _ := json.MarshalIndent(report, "", " ")
|
||
|
|
encoded = append(encoded, '\n')
|
||
|
|
if err = os.WriteFile(*outputPath, encoded, 0o600); err != nil {
|
||
|
|
fmt.Fprintln(os.Stderr, "write alert receiver report:", err)
|
||
|
|
os.Exit(2)
|
||
|
|
}
|
||
|
|
fmt.Printf("alert receiver conformance %s: %s\n", report.Result, *outputPath)
|
||
|
|
if report.Result != "PASS" {
|
||
|
|
os.Exit(1)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func readInputs(paths ...string) ([]byte, []byte, []byte, []byte, error) {
|
||
|
|
values := make([][]byte, 4)
|
||
|
|
for index, path := range paths {
|
||
|
|
content, err := os.ReadFile(path)
|
||
|
|
if err != nil {
|
||
|
|
return nil, nil, nil, nil, fmt.Errorf("read input %s: %w", filepath.Base(path), err)
|
||
|
|
}
|
||
|
|
values[index] = content
|
||
|
|
}
|
||
|
|
return values[0], values[1], values[2], values[3], nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func failInput(err error) {
|
||
|
|
fmt.Fprintln(os.Stderr, err)
|
||
|
|
os.Exit(2)
|
||
|
|
}
|