package main import ( "encoding/json" "flag" "fmt" "os" "path/filepath" "time" "data-terminal-cloud/internal/firmwareconformance" ) func main() { os.Exit(run()) } func run() int { cloudPath := flag.String("cloud", "", "path to a firmware rollout API JSON response") devicePath := flag.String("device", "", "path to firmware-device-evidence-v1 JSON") outputPath := flag.String("output", "", "path for the conformance report JSON") flag.Parse() if *cloudPath == "" || *devicePath == "" || *outputPath == "" { fmt.Fprintln(os.Stderr, "usage: firmware-conformance -cloud rollout.json -device device-evidence.json -output report.json") return 2 } if !filepath.IsAbs(*outputPath) { fmt.Fprintln(os.Stderr, "output path must be absolute") return 2 } cloudContent, err := os.ReadFile(*cloudPath) if err != nil { fmt.Fprintln(os.Stderr, "read cloud rollout:", err) return 2 } deviceContent, err := os.ReadFile(*devicePath) if err != nil { fmt.Fprintln(os.Stderr, "read device evidence:", err) return 2 } cloud, err := firmwareconformance.ParseCloud(cloudContent) if err != nil { fmt.Fprintln(os.Stderr, err) return 2 } device, err := firmwareconformance.ParseDeviceEvidence(deviceContent) if err != nil { fmt.Fprintln(os.Stderr, err) return 2 } report := firmwareconformance.Evaluate(cloud, device, time.Now().UTC()) report.InputSHA256["cloud_rollout"] = firmwareconformance.SHA256(cloudContent) report.InputSHA256["device_evidence"] = firmwareconformance.SHA256(deviceContent) content, err := json.MarshalIndent(report, "", " ") if err != nil { fmt.Fprintln(os.Stderr, "encode report:", err) return 2 } if err := os.WriteFile(*outputPath, append(content, '\n'), 0o600); err != nil { fmt.Fprintln(os.Stderr, "write report:", err) return 2 } fmt.Printf("firmware conformance %s: %s\n", report.Result, *outputPath) if report.Result != "PASS" { return 1 } return 0 }