diff options
author | Mike Crute <mike@crute.us> | 2022-05-22 00:59:57 -0700 |
---|---|---|
committer | Mike Crute <mike@crute.us> | 2022-05-22 00:59:57 -0700 |
commit | c34185d893311e31ecfbc72d4e306fb57e56e8fa (patch) | |
tree | cfe581cb9d9bf3398adc508e7cdd47bfb576904b /echo/echo_default.go | |
parent | d25729cef991e6136eede4931e3d46a76d473391 (diff) | |
download | golib-c34185d893311e31ecfbc72d4e306fb57e56e8fa.tar.bz2 golib-c34185d893311e31ecfbc72d4e306fb57e56e8fa.tar.xz golib-c34185d893311e31ecfbc72d4e306fb57e56e8fa.zip |
echo: completely decouple new/configecho/v0.7.0db/mongodb/v0.5.0
Diffstat (limited to 'echo/echo_default.go')
-rw-r--r-- | echo/echo_default.go | 299 |
1 files changed, 166 insertions, 133 deletions
diff --git a/echo/echo_default.go b/echo/echo_default.go index 6977eed..dcdda63 100644 --- a/echo/echo_default.go +++ b/echo/echo_default.go | |||
@@ -7,15 +7,13 @@ import ( | |||
7 | "html/template" | 7 | "html/template" |
8 | "io/fs" | 8 | "io/fs" |
9 | "net/http" | 9 | "net/http" |
10 | "os" | ||
11 | "sync" | 10 | "sync" |
12 | 11 | ||
13 | "code.crute.us/mcrute/golib/clients/netbox" | 12 | "code.crute.us/mcrute/golib/clients/netbox" |
14 | glautocert "code.crute.us/mcrute/golib/crypto/acme/autocert" | 13 | "code.crute.us/mcrute/golib/crypto/acme/autocert" |
15 | glmw "code.crute.us/mcrute/golib/echo/middleware" | 14 | glmw "code.crute.us/mcrute/golib/echo/middleware" |
16 | "code.crute.us/mcrute/golib/echo/prometheus" | 15 | "code.crute.us/mcrute/golib/echo/prometheus" |
17 | "code.crute.us/mcrute/golib/service" | 16 | "code.crute.us/mcrute/golib/service" |
18 | glservice "code.crute.us/mcrute/golib/service" | ||
19 | 17 | ||
20 | "github.com/labstack/echo/v4" | 18 | "github.com/labstack/echo/v4" |
21 | "github.com/labstack/echo/v4/middleware" | 19 | "github.com/labstack/echo/v4/middleware" |
@@ -54,13 +52,18 @@ func makeMiddlewareSkipper(c *prometheus.PrometheusConfig) middleware.Skipper { | |||
54 | } | 52 | } |
55 | } | 53 | } |
56 | 54 | ||
55 | // EchoConfig is the configuration for an EchoWrapper | ||
56 | // | ||
57 | // Service clients are generally passed in an only by interface even | ||
58 | // though we could create these internally so as to provide some | ||
59 | // isolation between what is (theoretically) a re-usable, though | ||
60 | // opinionated, Echo instance vs something that is completely custom to | ||
61 | // internal use-cases. | ||
57 | type EchoConfig struct { | 62 | type EchoConfig struct { |
58 | Autocert glautocert.PrimingCertProvider | 63 | Autocert autocert.PrimingCertProvider |
59 | NetboxClient netbox.NetboxClient | 64 | NetboxClient netbox.NetboxClient |
60 | ApplicationName string | 65 | ApplicationName string |
61 | ApplicationVersion string | 66 | ApplicationVersion string |
62 | DisableServerHeader bool | ||
63 | Debug bool | ||
64 | BindAddresses []string | 67 | BindAddresses []string |
65 | BodySizeLimit string | 68 | BodySizeLimit string |
66 | TrustedProxyIPRanges []string | 69 | TrustedProxyIPRanges []string |
@@ -77,12 +80,36 @@ type EchoConfig struct { | |||
77 | 80 | ||
78 | type EchoWrapper struct { | 81 | type EchoWrapper struct { |
79 | *echo.Echo | 82 | *echo.Echo |
80 | Autocert glautocert.PrimingCertProvider | 83 | runner *service.AppRunner |
81 | middlewareJobs []glservice.RunnerFunc | 84 | autocert autocert.PrimingCertProvider |
82 | middlewareInitJobs []glservice.SyncRunnerFunc | 85 | templateFS fs.FS |
83 | servers []*http.Server | 86 | } |
84 | tlsServers []*http.Server | 87 | |
85 | templateFS fs.FS | 88 | // NewEchoWrapper creates a new instance of Echo and wraps it in an |
89 | // internal wrapper that does configuration and service running. | ||
90 | // | ||
91 | // It is expected that Configure is called before using this Echo | ||
92 | // instance. | ||
93 | func NewEchoWrapper(ctx context.Context, debug bool) (*EchoWrapper, error) { | ||
94 | e := echo.New() | ||
95 | e.Debug = debug | ||
96 | |||
97 | e.Logger.SetLevel(log.INFO) | ||
98 | if debug { | ||
99 | e.Logger.SetLevel(log.DEBUG) | ||
100 | } | ||
101 | |||
102 | e.Use(middleware.Logger()) | ||
103 | e.Use(glmw.Recover()) | ||
104 | |||
105 | return &EchoWrapper{ | ||
106 | Echo: e, | ||
107 | runner: service.NewAppRunner(ctx, e.Logger), | ||
108 | }, nil | ||
109 | } | ||
110 | |||
111 | func (w *EchoWrapper) Runner() *service.AppRunner { | ||
112 | return w.runner | ||
86 | } | 113 | } |
87 | 114 | ||
88 | func (w *EchoWrapper) CachedStaticRoute(prefix, path string) { | 115 | func (w *EchoWrapper) CachedStaticRoute(prefix, path string) { |
@@ -92,214 +119,230 @@ func (w *EchoWrapper) CachedStaticRoute(prefix, path string) { | |||
92 | StaticFS(w.GET, w.templateFS, prefix, path, glmw.CacheOneMonthMiddleware) | 119 | StaticFS(w.GET, w.templateFS, prefix, path, glmw.CacheOneMonthMiddleware) |
93 | } | 120 | } |
94 | 121 | ||
95 | func (w *EchoWrapper) makeServerJob(s *http.Server, echoInit bool) glservice.RunnerFunc { | 122 | func (w *EchoWrapper) RunForever(enableBackgroundJobs bool) { |
96 | return func(ctx context.Context, wg *sync.WaitGroup) error { | 123 | w.runner.RunForever(enableBackgroundJobs) |
97 | wg.Add(1) | 124 | } |
98 | defer wg.Done() | ||
99 | 125 | ||
100 | w.Logger.Infof("Starting server with address: %s", s.Addr) | 126 | func (w *EchoWrapper) GetTemplateFS() fs.FS { |
127 | return w.templateFS | ||
128 | } | ||
101 | 129 | ||
102 | err := make(chan error) | 130 | func (w *EchoWrapper) Configure(c EchoConfig) error { |
103 | go func() { | 131 | w.configureAutocert(&c) |
104 | if s.TLSConfig == nil && echoInit { | ||
105 | err <- w.Echo.StartServer(s) | ||
106 | } else if s.TLSConfig == nil && !echoInit { | ||
107 | err <- s.ListenAndServe() | ||
108 | } else { | ||
109 | err <- s.ListenAndServeTLS("", "") | ||
110 | } | ||
111 | }() | ||
112 | select { | ||
113 | case e := <-err: | ||
114 | return e | ||
115 | default: | ||
116 | } | ||
117 | 132 | ||
118 | select { | 133 | if err := w.configureIpExtractor(&c); err != nil { |
119 | case <-ctx.Done(): | 134 | return err |
120 | w.Logger.Info("Shutting down web server") | ||
121 | return s.Shutdown(ctx) | ||
122 | } | ||
123 | } | 135 | } |
124 | } | ||
125 | 136 | ||
126 | func (w *EchoWrapper) makeServerJobs() []glservice.RunnerFunc { | 137 | if err := w.configureTemplates(&c); err != nil { |
127 | out := []glservice.RunnerFunc{} | 138 | return err |
139 | } | ||
128 | 140 | ||
129 | for i, s := range w.servers { | 141 | if err := w.configureCombinedLogging(&c); err != nil { |
130 | // The first http (not https) server should do an echo.StartServer to | 142 | return err |
131 | // configure some internal echo state and print the banner (if | ||
132 | // configured). | ||
133 | out = append(out, w.makeServerJob(s, i == 0)) | ||
134 | } | 143 | } |
135 | 144 | ||
136 | for _, s := range w.tlsServers { | 145 | bindings, err := ParseAddressPortBindings(c.BindAddresses) |
137 | out = append(out, w.makeServerJob(s, false)) | 146 | if err != nil { |
147 | return fmt.Errorf("Error parsing address/port bindings") | ||
138 | } | 148 | } |
139 | 149 | ||
140 | return out | 150 | w.buildServers(&c, bindings) |
141 | } | 151 | w.configureBodyLimit(&c) |
152 | w.configureRedirects(&c, bindings) | ||
153 | w.configureCompression(&c) | ||
142 | 154 | ||
143 | func (w *EchoWrapper) AddJobsToRunner(r *service.AppRunner) { | 155 | w.Use(glmw.StrictSecure()) |
144 | r.AddInitJob(w.Autocert.PrimeCache) | ||
145 | r.AddJob(w.Autocert.PrimingReporter(w.Logger)) | ||
146 | 156 | ||
147 | r.AddJobs(w.makeServerJobs()) | 157 | w.configureCORS(&c) |
158 | w.configureCSP(&c) | ||
159 | w.configureServerHeader(&c) | ||
160 | w.configurePrometheus(&c) | ||
148 | 161 | ||
149 | r.AddInitJobs(w.middlewareInitJobs) | 162 | return nil |
150 | r.AddJobs(w.middlewareJobs) | ||
151 | } | 163 | } |
152 | 164 | ||
153 | func (w *EchoWrapper) GetTemplateFS() fs.FS { | 165 | func (w *EchoWrapper) configureAutocert(c *EchoConfig) { |
154 | return w.templateFS | 166 | w.autocert = c.Autocert |
167 | w.runner.AddInitJob(w.autocert.PrimeCache) | ||
168 | w.runner.AddJob(w.autocert.PrimingReporter(w.Logger)) | ||
155 | } | 169 | } |
156 | 170 | ||
157 | // NewDefaultEchoWithConfig builds a wrapper around an Echo instance and | 171 | func (w *EchoWrapper) configureIpExtractor(c *EchoConfig) error { |
158 | // configures it in the default way that it should probably be configured in | ||
159 | // all cases. The struct returned from this function can be treated like a | ||
160 | // normal Echo instance (because, for the most part it is). | ||
161 | func NewDefaultEchoWithConfig(c EchoConfig) (*EchoWrapper, error) { | ||
162 | var err error | 172 | var err error |
163 | |||
164 | mwjobs := []glservice.RunnerFunc{} | ||
165 | mwinitjobs := []glservice.SyncRunnerFunc{} | ||
166 | |||
167 | if os.Getenv("POMONA_DC_SITE") == "" { | ||
168 | return nil, fmt.Errorf("POMONA_DC_SITE must be in the environment") | ||
169 | } | ||
170 | |||
171 | e := echo.New() | ||
172 | e.Debug = c.Debug | ||
173 | |||
174 | // This is only required if the app is behind a proxy, for apps that | 173 | // This is only required if the app is behind a proxy, for apps that |
175 | // take traffic directly from the internet the IP should just be | 174 | // take traffic directly from the internet the IP should just be |
176 | // extracted from the requests RemoteAddr. | 175 | // extracted from the requests RemoteAddr. |
177 | if c.TrustedProxyIPRanges == nil { | 176 | if c.TrustedProxyIPRanges == nil { |
178 | e.IPExtractor, err = glmw.ExtractIPFromXFFHeaders(false, c.TrustedProxyIPRanges) | 177 | w.IPExtractor, err = glmw.ExtractIPFromXFFHeaders(false, c.TrustedProxyIPRanges) |
179 | if err != nil { | 178 | if err != nil { |
180 | return nil, fmt.Errorf("Error building XFF IP extractor: %w", err) | 179 | return fmt.Errorf("Error building XFF IP extractor: %w", err) |
181 | } | 180 | } |
182 | } else { | 181 | } else { |
183 | e.IPExtractor = echo.ExtractIPDirect() | 182 | w.IPExtractor = echo.ExtractIPDirect() |
184 | } | 183 | } |
184 | return nil | ||
185 | } | ||
185 | 186 | ||
187 | func (w *EchoWrapper) configureTemplates(c *EchoConfig) error { | ||
186 | // Use templates from disk in debug mode and the embedded ones that are | 188 | // Use templates from disk in debug mode and the embedded ones that are |
187 | // built-in to the binary for prod mode. | 189 | // built-in to the binary for prod mode. |
188 | var templates fs.FS | 190 | var templates fs.FS |
189 | if c.DiskTemplates != nil && c.Debug { // Debug Mode | 191 | |
192 | if c.DiskTemplates != nil && w.Debug { // Debug Mode | ||
190 | templates = c.DiskTemplates | 193 | templates = c.DiskTemplates |
191 | } else if c.EmbeddedTemplates != nil && !c.Debug { // Prod Mode | 194 | } else if c.EmbeddedTemplates != nil && !w.Debug { // Prod Mode |
192 | templates = c.EmbeddedTemplates | 195 | templates = c.EmbeddedTemplates |
193 | } | 196 | } |
194 | 197 | ||
195 | // Only install template handlers if the path and glob are set | 198 | // Only install template handlers if the path and glob are set |
196 | if templates != nil { | 199 | if templates != nil { |
197 | e.HTTPErrorHandler = ErrorHandler(templates, c.TemplateFunctions) | 200 | w.HTTPErrorHandler = ErrorHandler(templates, c.TemplateFunctions) |
198 | 201 | ||
199 | tr, err := NewTemplateRenderer(templates, "*.tpl", c.TemplateFunctions) | 202 | tr, err := NewTemplateRenderer(templates, "*.tpl", c.TemplateFunctions) |
200 | if err != nil { | 203 | if err != nil { |
201 | return nil, fmt.Errorf("Error loading template renderer: %w", err) | 204 | return fmt.Errorf("Error loading template renderer: %w", err) |
202 | } | 205 | } |
203 | e.Renderer = tr | 206 | w.Renderer = tr |
204 | 207 | ||
205 | for _, t := range mandatoryTemplates { | 208 | for _, t := range mandatoryTemplates { |
206 | if !tr.HaveTemplate(e.NewContext(nil, nil), t) { | 209 | if !tr.HaveTemplate(w.NewContext(nil, nil), t) { |
207 | return nil, fmt.Errorf("Tempalate renderer is missing required template %s", t) | 210 | return fmt.Errorf("Tempalate renderer is missing required template %s", t) |
208 | } | 211 | } |
209 | } | 212 | } |
210 | } | 213 | } |
211 | 214 | ||
212 | e.Logger.SetLevel(log.INFO) | 215 | w.templateFS = templates |
213 | if c.Debug { | 216 | return nil |
214 | e.Logger.SetLevel(log.DEBUG) | 217 | } |
215 | } | ||
216 | 218 | ||
219 | func (w *EchoWrapper) configureCombinedLogging(c *EchoConfig) error { | ||
217 | if c.CombinedHostLogFile != "" { | 220 | if c.CombinedHostLogFile != "" { |
218 | lc, err := NginxCombinedHostConfigToFile(c.CombinedHostLogFile) | 221 | lc, err := NginxCombinedHostConfigToFile(c.CombinedHostLogFile) |
219 | if err != nil { | 222 | if err != nil { |
220 | return nil, fmt.Errorf("Error opening log file: %w", err) | 223 | return fmt.Errorf("Error opening log file: %w", err) |
221 | } | 224 | } |
222 | e.Use(middleware.LoggerWithConfig(lc)) | 225 | w.Use(middleware.LoggerWithConfig(lc)) |
223 | } | 226 | } |
227 | return nil | ||
228 | } | ||
224 | 229 | ||
225 | bindings, err := ParseAddressPortBindings(c.BindAddresses) | 230 | func (w *EchoWrapper) makeServerJob(s *http.Server, echoInit bool) service.RunnerFunc { |
226 | if err != nil { | 231 | return func(ctx context.Context, wg *sync.WaitGroup) error { |
227 | return nil, fmt.Errorf("Error parsing address/port bindings") | 232 | wg.Add(1) |
233 | defer wg.Done() | ||
234 | |||
235 | w.Logger.Infof("Starting server with address: %s", s.Addr) | ||
236 | |||
237 | err := make(chan error) | ||
238 | go func() { | ||
239 | if s.TLSConfig == nil && echoInit { | ||
240 | err <- w.Echo.StartServer(s) | ||
241 | } else if s.TLSConfig == nil && !echoInit { | ||
242 | err <- s.ListenAndServe() | ||
243 | } else { | ||
244 | err <- s.ListenAndServeTLS("", "") | ||
245 | } | ||
246 | }() | ||
247 | select { | ||
248 | case e := <-err: | ||
249 | return e | ||
250 | default: | ||
251 | } | ||
252 | |||
253 | select { | ||
254 | case <-ctx.Done(): | ||
255 | w.Logger.Info("Shutting down web server") | ||
256 | return s.Shutdown(ctx) | ||
257 | } | ||
228 | } | 258 | } |
259 | } | ||
229 | 260 | ||
230 | servers := make([]*http.Server, len(c.BindAddresses)) | 261 | func (w *EchoWrapper) buildServers(c *EchoConfig, bindings *AddressPortConfig) { |
231 | for i, a := range bindings.HttpBindings() { | 262 | for i, a := range bindings.HttpBindings() { |
232 | servers[i] = &http.Server{ | 263 | s := &http.Server{ |
233 | Addr: a, | 264 | Addr: a, |
234 | Handler: e, | 265 | Handler: w, |
235 | } | 266 | } |
267 | w.runner.AddJob(w.makeServerJob(s, i == 0)) | ||
236 | } | 268 | } |
237 | 269 | ||
238 | tlsServers := make([]*http.Server, len(c.BindAddresses)) | 270 | for _, a := range bindings.TlsBindings() { |
239 | for i, a := range bindings.TlsBindings() { | 271 | s := &http.Server{ |
240 | tlsServers[i] = &http.Server{ | ||
241 | Addr: a, | 272 | Addr: a, |
242 | TLSConfig: &tls.Config{ | 273 | TLSConfig: &tls.Config{ |
243 | MinVersion: tls.VersionTLS12, | 274 | MinVersion: tls.VersionTLS12, |
244 | GetCertificate: c.Autocert.GetCertificate, | 275 | GetCertificate: c.Autocert.GetCertificate, |
245 | NextProtos: []string{"h2", "http/1.1"}, // enable HTTP/2 | 276 | NextProtos: []string{"h2", "http/1.1"}, // enable HTTP/2 |
246 | }, | 277 | }, |
247 | Handler: e, | 278 | Handler: w, |
248 | } | 279 | } |
280 | w.runner.AddJob(w.makeServerJob(s, false)) | ||
249 | } | 281 | } |
282 | } | ||
250 | 283 | ||
251 | metricsSkipper := makeMiddlewareSkipper(c.PrometheusConfig) | 284 | func (w *EchoWrapper) configureBodyLimit(c *EchoConfig) { |
252 | |||
253 | e.Use(middleware.Logger()) | ||
254 | e.Use(glmw.Recover()) | ||
255 | |||
256 | if c.BodySizeLimit == "" { | 285 | if c.BodySizeLimit == "" { |
257 | e.Use(middleware.BodyLimit(defaultBodySizeLimit)) | 286 | w.Use(middleware.BodyLimit(defaultBodySizeLimit)) |
258 | } else if c.BodySizeLimit != "0" { | 287 | } else if c.BodySizeLimit != "0" { |
259 | e.Use(middleware.BodyLimit(c.BodySizeLimit)) | 288 | w.Use(middleware.BodyLimit(c.BodySizeLimit)) |
260 | } | 289 | } |
290 | } | ||
291 | |||
292 | func (w *EchoWrapper) configureRedirects(c *EchoConfig, bindings *AddressPortConfig) { | ||
293 | metricsSkipper := makeMiddlewareSkipper(c.PrometheusConfig) | ||
261 | 294 | ||
262 | e.Use(glmw.HTTPSRedirectWithConfig(glmw.HTTPSRedirectConfig{ | 295 | w.Use(glmw.HTTPSRedirectWithConfig(glmw.HTTPSRedirectConfig{ |
263 | Skipper: metricsSkipper, | 296 | Skipper: metricsSkipper, |
264 | Port: bindings.TlsPort, | 297 | Port: bindings.TlsPort, |
265 | })) | 298 | })) |
266 | 299 | ||
267 | if c.RedirectToWWW { | 300 | if c.RedirectToWWW { |
268 | e.Use(middleware.WWWRedirectWithConfig(middleware.RedirectConfig{ | 301 | w.Use(middleware.WWWRedirectWithConfig(middleware.RedirectConfig{ |
269 | Skipper: metricsSkipper, | 302 | Skipper: metricsSkipper, |
270 | })) | 303 | })) |
271 | } | 304 | } |
305 | } | ||
272 | 306 | ||
273 | e.Use(middleware.Decompress()) | 307 | func (w *EchoWrapper) configureCompression(c *EchoConfig) { |
308 | metricsSkipper := makeMiddlewareSkipper(c.PrometheusConfig) | ||
309 | |||
310 | w.Use(middleware.Decompress()) | ||
274 | 311 | ||
275 | // TODO: This mangles responses but only for Accept: */* (browsers). Why? | 312 | // TODO: This mangles responses but only for Accept: */* (browsers). Why? |
276 | e.Use(middleware.GzipWithConfig(middleware.GzipConfig{ | 313 | w.Use(middleware.GzipWithConfig(middleware.GzipConfig{ |
277 | Skipper: metricsSkipper, | 314 | Skipper: metricsSkipper, |
278 | Level: 5, | 315 | Level: 5, |
279 | })) | 316 | })) |
317 | } | ||
280 | 318 | ||
281 | e.Use(glmw.StrictSecure()) | 319 | func (w *EchoWrapper) configureCORS(c *EchoConfig) { |
282 | |||
283 | if c.CORSConfig != nil { | 320 | if c.CORSConfig != nil { |
284 | e.Use(middleware.CORSWithConfig(*c.CORSConfig)) | 321 | w.Use(middleware.CORSWithConfig(*c.CORSConfig)) |
285 | } else { | 322 | } else { |
286 | e.Use(middleware.CORS()) | 323 | w.Use(middleware.CORS()) |
287 | } | 324 | } |
325 | } | ||
288 | 326 | ||
327 | func (w *EchoWrapper) configureCSP(c *EchoConfig) { | ||
289 | if c.ContentSecurityPolicy != nil { | 328 | if c.ContentSecurityPolicy != nil { |
290 | e.Use(glmw.ContentSecurityPolicyWithConfig(*c.ContentSecurityPolicy)) | 329 | w.Use(glmw.ContentSecurityPolicyWithConfig(*c.ContentSecurityPolicy)) |
291 | } else { | 330 | } else { |
292 | e.Use(glmw.ContentSecurityPolicyWithConfig(glmw.ContentSecurityPolicyConfig{ | 331 | w.Use(glmw.ContentSecurityPolicyWithConfig(glmw.ContentSecurityPolicyConfig{ |
293 | DefaultSrc: []glmw.CSPDirective{ | 332 | DefaultSrc: []glmw.CSPDirective{ |
294 | glmw.CSPSelf, | 333 | glmw.CSPSelf, |
295 | }, | 334 | }, |
296 | })) | 335 | })) |
297 | } | 336 | } |
337 | } | ||
298 | 338 | ||
299 | if c.ApplicationName != "" && c.ApplicationVersion != "" && !c.DisableServerHeader { | 339 | func (w *EchoWrapper) configureServerHeader(c *EchoConfig) { |
300 | e.Use(glmw.AddServerHeader(c.ApplicationName, c.ApplicationVersion)) | 340 | if c.ApplicationName != "" && c.ApplicationVersion != "" { |
341 | w.Use(glmw.AddServerHeader(c.ApplicationName, c.ApplicationVersion)) | ||
301 | } | 342 | } |
343 | } | ||
302 | 344 | ||
345 | func (w *EchoWrapper) configurePrometheus(c *EchoConfig) { | ||
303 | if !c.DisablePrometheus && c.NetboxClient != nil { | 346 | if !c.DisablePrometheus && c.NetboxClient != nil { |
304 | // TODO: Should constrain this by site probably but monitoring happens | 347 | // TODO: Should constrain this by site probably but monitoring happens |
305 | // across sites so those prefixes need to be included | 348 | // across sites so those prefixes need to be included |
@@ -307,10 +350,10 @@ func NewDefaultEchoWithConfig(c EchoConfig) (*EchoWrapper, error) { | |||
307 | NetboxClient: c.NetboxClient, | 350 | NetboxClient: c.NetboxClient, |
308 | Tag: "management", | 351 | Tag: "management", |
309 | IncludeLocalhost: true, | 352 | IncludeLocalhost: true, |
310 | Logger: e.Logger, | 353 | Logger: w.Logger, |
311 | } | 354 | } |
312 | mwinitjobs = append(mwinitjobs, f.Init) | 355 | w.runner.AddInitJob(f.Init) |
313 | mwjobs = append(mwjobs, f.RunRefresh) | 356 | w.runner.AddJob(f.RunRefresh) |
314 | 357 | ||
315 | var prom *prometheus.Prometheus | 358 | var prom *prometheus.Prometheus |
316 | if c.PrometheusConfig != nil { | 359 | if c.PrometheusConfig != nil { |
@@ -319,17 +362,7 @@ func NewDefaultEchoWithConfig(c EchoConfig) (*EchoWrapper, error) { | |||
319 | prom = prometheus.NewPrometheus() | 362 | prom = prometheus.NewPrometheus() |
320 | } | 363 | } |
321 | 364 | ||
322 | e.Use(prom.MiddlewareHandler) | 365 | w.Use(prom.MiddlewareHandler) |
323 | e.GET(prom.Config.MetricsPath, prom.MetricsHandler, f.Middleware) | 366 | w.GET(prom.Config.MetricsPath, prom.MetricsHandler, f.Middleware) |
324 | } | 367 | } |
325 | |||
326 | return &EchoWrapper{ | ||
327 | Echo: e, | ||
328 | Autocert: c.Autocert, | ||
329 | servers: servers, | ||
330 | tlsServers: tlsServers, | ||
331 | templateFS: templates, | ||
332 | middlewareJobs: mwjobs, | ||
333 | middlewareInitJobs: mwinitjobs, | ||
334 | }, nil | ||
335 | } | 368 | } |