-
Notifications
You must be signed in to change notification settings - Fork 142
/
redoctober.go
155 lines (132 loc) · 4.39 KB
/
redoctober.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Copyright (c) 2013 CloudFlare, Inc.
package main
import (
"flag"
"fmt"
"log"
"net"
"net/http"
"os"
"strings"
"github.com/cloudflare/redoctober/config"
"github.com/cloudflare/redoctober/core"
"github.com/cloudflare/redoctober/report"
"github.com/cloudflare/redoctober/server"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// initPrometheus starts a goroutine with a Prometheus listener that
// listens on localhost:metricsPort. If the Prometheus handler can't
// be started, a log.Fatal call is made.
func initPrometheus() {
srv := &http.Server{
Addr: net.JoinHostPort(cfg.Metrics.Host, cfg.Metrics.Port),
Handler: promhttp.Handler(),
}
log.Printf("metrics.init start: addr=%s", srv.Addr)
go func() {
err := srv.ListenAndServe()
report.Check(err, nil)
log.Fatal(err.Error())
}()
}
const usage = `Usage:
redoctober -static <path> -vaultpath <path> -addr <addr> -certs <path1>[,<path2>,...] -keys <path1>[,<path2>,...] [-ca <path>]
single-cert example:
redoctober -vaultpath diskrecord.json -addr localhost:8080 -certs cert.pem -keys cert.key
multi-cert example:
redoctober -vaultpath diskrecord.json -addr localhost:8080 -certs cert1.pem,cert2.pem -keys cert1.key,cert2.key
`
var (
cfg, cli *config.Config
confFile string
vaultPath string
)
const (
defaultAddr = "localhost:8080"
defaultMetricsHost = "localhost"
defaultMetricsPort = "8081"
)
func registerCli() {
// cli contains the configuration set by the command line
// options, and cfg is the actual Red October config.
cli = config.New()
cfg = config.New()
// customized the default index html with auto generated content
server.DefaultIndexHTML = indexHTML
cli.Server.Addr = defaultAddr
cli.Metrics.Host = defaultMetricsHost
cli.Metrics.Port = defaultMetricsPort
flag.Usage = func() {
fmt.Fprint(os.Stderr, "main usage dump\n")
fmt.Fprint(os.Stderr, usage)
flag.PrintDefaults()
os.Exit(2)
}
flag.StringVar(&confFile, "f", "", "path to config file")
flag.StringVar(&cli.Server.Addr, "addr", cli.Server.Addr,
"Server and port separated by :")
flag.StringVar(&cli.Server.CAPath, "ca", cli.Server.CAPath,
"Path of TLS CA for client authentication (optional)")
flag.StringVar(&cli.Server.CertPaths, "certs", cli.Server.CertPaths,
"Path(s) of TLS certificate in PEM format, comma-separated")
flag.StringVar(&cli.HipChat.Host, "hchost", cli.HipChat.Host,
"Hipchat Url Base (ex: hipchat.com)")
flag.StringVar(&cli.HipChat.APIKey, "hckey", cli.HipChat.APIKey,
"Hipchat API Key")
flag.StringVar(&cli.HipChat.Room, "hcroom", cli.HipChat.Room,
"Hipchat Room ID")
flag.StringVar(&cli.Server.KeyPaths, "keys", cli.Server.KeyPaths,
"Comma-separated list of PEM-encoded TLS private keys in the same order as certs")
flag.StringVar(&cli.Metrics.Host, "metrics-host", cli.Metrics.Host,
"The `host` the metrics endpoint should listen on.")
flag.StringVar(&cli.Metrics.Port, "metrics-port", cli.Metrics.Port,
"The `port` the metrics endpoint should listen on.")
flag.StringVar(&cli.UI.Root, "rohost", cli.UI.Root, "RedOctober URL Base (ex: localhost:8080)")
flag.StringVar(&cli.UI.Static, "static", cli.UI.Static,
"Path to override built-in index.html")
flag.BoolVar(&cli.Server.Systemd, "systemdfds", cli.Server.Systemd,
"Use systemd socket activation to listen on a file. Useful for binding privileged sockets.")
flag.StringVar(&vaultPath, "vaultpath", "diskrecord.json", "Path to the the disk vault")
flag.Parse()
}
//go:generate go run generate.go
func main() {
registerCli()
var err error
if confFile != "" {
cfg, err = config.Load(confFile)
if err != nil {
log.Fatal(err)
}
} else {
cfg = cli
}
report.Init(cfg)
if vaultPath == "" || !cfg.Valid() {
if !cfg.Valid() {
fmt.Fprintf(os.Stderr, "Invalid config.\n")
}
fmt.Fprint(os.Stderr, usage)
flag.PrintDefaults()
os.Exit(2)
}
if err := core.Init(vaultPath, cfg); err != nil {
report.Check(err, nil)
log.Fatal(err)
}
initPrometheus()
cpaths := strings.Split(cfg.Server.CertPaths, ",")
kpaths := strings.Split(cfg.Server.KeyPaths, ",")
s, l, err := server.NewServer(cfg.UI.Static, cfg.Server.Addr, cfg.Server.CAPath,
cpaths, kpaths, cfg.Server.Systemd)
if err != nil {
report.Check(err, nil)
log.Fatalf("Error starting redoctober server: %s\n", err)
}
log.Printf("http.serve start: addr=%s", cfg.Server.Addr)
report.Recover(func() {
err := s.Serve(l)
report.Check(err, nil)
log.Fatal(err.Error())
})
}