1 package notmain
2
3 import (
4 "context"
5 "errors"
6 "flag"
7 "os"
8 "time"
9
10 capb "github.com/letsencrypt/boulder/ca/proto"
11 "github.com/letsencrypt/boulder/cmd"
12 "github.com/letsencrypt/boulder/config"
13 cspb "github.com/letsencrypt/boulder/crl/storer/proto"
14 "github.com/letsencrypt/boulder/crl/updater"
15 "github.com/letsencrypt/boulder/features"
16 bgrpc "github.com/letsencrypt/boulder/grpc"
17 "github.com/letsencrypt/boulder/issuance"
18 sapb "github.com/letsencrypt/boulder/sa/proto"
19 )
20
21 type Config struct {
22 CRLUpdater struct {
23 DebugAddr string
24
25
26 TLS cmd.TLSConfig
27
28 SAService *cmd.GRPCClientConfig
29 CRLGeneratorService *cmd.GRPCClientConfig
30 CRLStorerService *cmd.GRPCClientConfig
31
32
33
34
35 IssuerCerts []string `validate:"min=1,dive,required"`
36
37
38
39
40
41 NumShards int `validate:"min=1"`
42
43
44
45
46
47
48
49
50 ShardWidth config.Duration `validate:"-"`
51
52
53
54
55
56
57 LookbackPeriod config.Duration `validate:"-"`
58
59
60
61
62
63
64
65
66
67
68 CertificateLifetime config.Duration `validate:"-"`
69
70
71
72
73
74
75 UpdatePeriod config.Duration
76
77
78
79
80
81
82
83
84 UpdateOffset config.Duration `validate:"-"`
85
86
87
88
89
90
91
92 UpdateTimeout config.Duration `validate:"-"`
93
94
95
96
97
98 MaxParallelism int `validate:"min=0"`
99
100
101
102
103
104 MaxAttempts int `validate:"omitempty,min=1"`
105
106 Features map[string]bool
107 }
108
109 Syslog cmd.SyslogConfig
110 OpenTelemetry cmd.OpenTelemetryConfig
111 }
112
113 func main() {
114 configFile := flag.String("config", "", "File path to the configuration file for this service")
115 debugAddr := flag.String("debug-addr", "", "Debug server address override")
116 runOnce := flag.Bool("runOnce", false, "If true, run once immediately and then exit")
117 flag.Parse()
118 if *configFile == "" {
119 flag.Usage()
120 os.Exit(1)
121 }
122
123 var c Config
124 err := cmd.ReadConfigFile(*configFile, &c)
125 cmd.FailOnError(err, "Reading JSON config file into config structure")
126
127 if *debugAddr != "" {
128 c.CRLUpdater.DebugAddr = *debugAddr
129 }
130
131 err = features.Set(c.CRLUpdater.Features)
132 cmd.FailOnError(err, "Failed to set feature flags")
133
134 scope, logger, oTelShutdown := cmd.StatsAndLogging(c.Syslog, c.OpenTelemetry, c.CRLUpdater.DebugAddr)
135 defer oTelShutdown(context.Background())
136 logger.Info(cmd.VersionString())
137 clk := cmd.Clock()
138
139 tlsConfig, err := c.CRLUpdater.TLS.Load(scope)
140 cmd.FailOnError(err, "TLS config")
141
142 issuers := make([]*issuance.Certificate, 0, len(c.CRLUpdater.IssuerCerts))
143 for _, filepath := range c.CRLUpdater.IssuerCerts {
144 cert, err := issuance.LoadCertificate(filepath)
145 cmd.FailOnError(err, "Failed to load issuer cert")
146 issuers = append(issuers, cert)
147 }
148
149 if c.CRLUpdater.ShardWidth.Duration == 0 {
150 c.CRLUpdater.ShardWidth.Duration = 16 * time.Hour
151 }
152 if c.CRLUpdater.LookbackPeriod.Duration == 0 {
153 c.CRLUpdater.LookbackPeriod.Duration = 24 * time.Hour
154 }
155 if c.CRLUpdater.UpdateTimeout.Duration == 0 {
156 c.CRLUpdater.UpdateTimeout.Duration = 10 * time.Minute
157 }
158
159 saConn, err := bgrpc.ClientSetup(c.CRLUpdater.SAService, tlsConfig, scope, clk)
160 cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to SA")
161 sac := sapb.NewStorageAuthorityClient(saConn)
162
163 caConn, err := bgrpc.ClientSetup(c.CRLUpdater.CRLGeneratorService, tlsConfig, scope, clk)
164 cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to CRLGenerator")
165 cac := capb.NewCRLGeneratorClient(caConn)
166
167 csConn, err := bgrpc.ClientSetup(c.CRLUpdater.CRLStorerService, tlsConfig, scope, clk)
168 cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to CRLStorer")
169 csc := cspb.NewCRLStorerClient(csConn)
170
171 u, err := updater.NewUpdater(
172 issuers,
173 c.CRLUpdater.NumShards,
174 c.CRLUpdater.ShardWidth.Duration,
175 c.CRLUpdater.LookbackPeriod.Duration,
176 c.CRLUpdater.UpdatePeriod.Duration,
177 c.CRLUpdater.UpdateTimeout.Duration,
178 c.CRLUpdater.MaxParallelism,
179 c.CRLUpdater.MaxAttempts,
180 sac,
181 cac,
182 csc,
183 scope,
184 logger,
185 clk,
186 )
187 cmd.FailOnError(err, "Failed to create crl-updater")
188
189 ctx, cancel := context.WithCancel(context.Background())
190 go cmd.CatchSignals(cancel)
191
192 if *runOnce {
193 err = u.RunOnce(ctx)
194 if err != nil && !errors.Is(err, context.Canceled) {
195 cmd.FailOnError(err, "")
196 }
197 } else {
198 err = u.Run(ctx)
199 if err != nil && !errors.Is(err, context.Canceled) {
200 cmd.FailOnError(err, "")
201 }
202 }
203 }
204
205 func init() {
206 cmd.RegisterCommand("crl-updater", main, &cmd.ConfigValidator{Config: &Config{}})
207 }
208
View as plain text