diff --git a/tesseract/genconf/main.go b/tesseract/genconf/main.go index 9484b1d..98b530d 100644 --- a/tesseract/genconf/main.go +++ b/tesseract/genconf/main.go @@ -8,9 +8,11 @@ import ( "encoding/pem" "flag" "fmt" + "io" "log" "os" "path/filepath" + "strings" "text/template" "time" @@ -20,6 +22,7 @@ import ( type Config struct { Listen []string `yaml:"listen"` Checkpoints string `yaml:"checkpoints"` + Roots string `yaml:"roots"` Logs []Log `yaml:"logs"` } @@ -112,7 +115,7 @@ const htmlTemplate = ` key get-roots - json
+ json
Ratelimit: {{.PoolSize}} req/s
{{.PublicKeyPEM}}
@@ -135,6 +138,8 @@ func main() { switch args[0] { case "gen-html": generateHTML(*configFile) + case "gen-env": + generateEnv(*configFile) default: fmt.Fprintf(os.Stderr, "Unknown command: %s\n", args[0]) os.Exit(1) @@ -311,3 +316,84 @@ func generateLogJSON(logEntry Log, outputPath string) error { return nil } + +func generateEnv(yamlFile string) { + config := loadConfig(yamlFile) + + // Check that all local directories exist + for _, logEntry := range config.Logs { + if _, err := os.Stat(logEntry.LocalDirectory); os.IsNotExist(err) { + log.Fatalf("User is required to create %s", logEntry.LocalDirectory) + } + } + + // Generate .env file for each log + for _, logEntry := range config.Logs { + envPath := filepath.Join(logEntry.LocalDirectory, ".env") + + // Create combined roots.pem file + rootsPemPath := filepath.Join(logEntry.LocalDirectory, "roots.pem") + err := createCombinedRootsPem(config.Roots, logEntry.ExtraRoots, rootsPemPath) + if err != nil { + log.Fatalf("Failed to create %s: %v", rootsPemPath, err) + } + fmt.Printf("Generated %s\n", rootsPemPath) + + // Build TESSERACT_ARGS string + args := []string{ + fmt.Sprintf("--private_key=%s", logEntry.Secret), + fmt.Sprintf("--origin=%s.log.ct.ipng.ch", logEntry.ShortName), + fmt.Sprintf("--storage_dir=%s", logEntry.LocalDirectory), + fmt.Sprintf("--roots_pem_file=%s", rootsPemPath), + } + + tesseractArgs := strings.Join(args, " ") + envContent := fmt.Sprintf("TESSERACT_ARGS=\"%s\"\n", tesseractArgs) + + err = os.WriteFile(envPath, []byte(envContent), 0644) + if err != nil { + log.Fatalf("Failed to write %s: %v", envPath, err) + } + + fmt.Printf("Generated %s\n", envPath) + } +} + +func createCombinedRootsPem(rootsFile, extraRootsFile, outputPath string) error { + // Create output file + outputFile, err := os.Create(outputPath) + if err != nil { + return fmt.Errorf("failed to create output file: %v", err) + } + defer outputFile.Close() + + // Copy main roots file + if rootsFile != "" { + rootsData, err := os.Open(rootsFile) + if err != nil { + return fmt.Errorf("failed to open roots file %s: %v", rootsFile, err) + } + defer rootsData.Close() + + _, err = io.Copy(outputFile, rootsData) + if err != nil { + return fmt.Errorf("failed to copy roots file: %v", err) + } + } + + // Append extra roots file if it exists + if extraRootsFile != "" { + extraRootsData, err := os.Open(extraRootsFile) + if err != nil { + return fmt.Errorf("failed to open extra roots file %s: %v", extraRootsFile, err) + } + defer extraRootsData.Close() + + _, err = io.Copy(outputFile, extraRootsData) + if err != nil { + return fmt.Errorf("failed to copy extra roots file: %v", err) + } + } + + return nil +}