Files
cheese/tesseract/genconf/nginx.go

161 lines
4.2 KiB
Go

package main
import (
"bytes"
"fmt"
"net/url"
"os"
"path/filepath"
"strings"
"text/template"
)
const nginxTemplate = `server {
listen {{.ListenPort}};
listen [::]:{{.ListenPort}};
# Replace with your actual domain(s)
server_name {{.MonitoringHost}};
# Document root for static files
root {{.LocalDirectory}};
location = / {
try_files /index.html =404;
add_header Content-Type "text/html; charset=utf-8" always;
add_header Access-Control-Allow-Origin "*" always;
}
# Checkpoint endpoint - no caching
location = /checkpoint {
try_files /checkpoint =404;
add_header Content-Type "text/plain; charset=utf-8" always;
add_header Access-Control-Allow-Origin "*" always;
add_header Cache-Control "no-store" always;
}
# Log info endpoint
location = /log.v3.json {
try_files /log.v3.json =404;
add_header Content-Type "application/json" always;
add_header Access-Control-Allow-Origin "*" always;
add_header Cache-Control "public, max-age=3600, immutable" always;
}
# Issuer certificate endpoint - long cache
location ~ ^/issuer/(.+)$ {
try_files /issuer/$1 =404;
add_header Content-Type "application/pkix-cert" always;
add_header Access-Control-Allow-Origin "*" always;
add_header Cache-Control "public, max-age=604800, immutable" always;
}
# Tile data endpoint - long cache, may have gzip
location ~ ^/tile/(.+)$ {
try_files /tile/$1 =404;
add_header Content-Type "application/octet-stream" always;
add_header Access-Control-Allow-Origin "*" always;
add_header Cache-Control "public, max-age=604800, immutable" always;
# Gzip encoding for .gz files
location ~ \.gz$ {
add_header Content-Encoding "gzip" always;
}
}
}
`
type NginxTemplateData struct {
MonitoringHost string
LocalDirectory string
ListenPort string
}
func generateNginx(yamlFile string, wantDiff bool, allowWrite bool, useColor bool) {
config := loadConfig(yamlFile)
// Extract port from first listen address
listenPort := "8080" // fallback default
if len(config.Listen) > 0 {
port := extractPort(config.Listen[0])
if port != "" {
listenPort = port
}
}
for _, log := range config.Logs {
// Extract hostname from monitoring prefix
hostname, err := extractHostname(log.MonitoringPrefix)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to extract hostname from %s: %v\n", log.MonitoringPrefix, err)
continue
}
// Create template data
data := NginxTemplateData{
MonitoringHost: hostname,
LocalDirectory: log.LocalDirectory,
ListenPort: listenPort,
}
// Parse and execute template
tmpl, err := template.New("nginx").Parse(nginxTemplate)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to parse nginx template: %v\n", err)
continue
}
// Generate output filename using only hostname part
outputFilename := fmt.Sprintf("%s.conf", hostname)
outputPath := filepath.Join(log.LocalDirectory, outputFilename)
// Execute template to buffer
var buf bytes.Buffer
err = tmpl.Execute(&buf, data)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to execute nginx template for %s: %v\n", outputPath, err)
continue
}
// Write file with status
err = writeFileWithStatus(outputPath, buf.Bytes(), wantDiff, allowWrite, useColor)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to write nginx config file %s: %v\n", outputPath, err)
continue
}
}
}
func extractPort(listenAddr string) string {
// Handle common listen address formats:
// ":8080" -> "8080"
// "localhost:8080" -> "8080"
// "[::]:8080" -> "8080"
if strings.HasPrefix(listenAddr, ":") {
return listenAddr[1:] // Remove the leading ":"
}
// For addresses with host:port format
if strings.Contains(listenAddr, ":") {
parts := strings.Split(listenAddr, ":")
return parts[len(parts)-1] // Return the last part (port)
}
return ""
}
func extractHostname(urlStr string) (string, error) {
parsedURL, err := url.Parse(urlStr)
if err != nil {
return "", err
}
return parsedURL.Host, nil
}