From 19d1b7ce0c9e52182542ff9e447a59846c6948af Mon Sep 17 00:00:00 2001 From: Bharath B Date: Wed, 22 Nov 2023 09:47:46 +0530 Subject: [PATCH] CFE-986: Reload router when defaultDestinationCA is updated --- pkg/router/router_test.go | 18 ++++++++++++------ pkg/router/template/router.go | 27 +++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/pkg/router/router_test.go b/pkg/router/router_test.go index ae033a367..0686e13e4 100644 --- a/pkg/router/router_test.go +++ b/pkg/router/router_test.go @@ -101,19 +101,25 @@ func TestMain(m *testing.M) { h.workdir = workdir h.dirs = map[string]string{ - "whitelist": filepath.Join(workdir, "router", "whitelists"), + "whitelist": filepath.Join(workdir, "router", "whitelists"), + "cabundle": filepath.Join(workdir, "ca-trust"), + "cabundle-data": filepath.Join(workdir, "ca-trust", "..data/"), } createRouterDirs() + defaultDestinationCA := filepath.Join(h.dirs["cabundle"], "ca-bundle.crt") + os.Create(filepath.Join(h.dirs["cabundle-data"], "ca-bundle.crt")) + os.Symlink(filepath.Join(h.dirs["cabundle-data"], "ca-bundle.crt"), defaultDestinationCA) // The template plugin which is wrapped svcFetcher := templateplugin.NewListWatchServiceLookup(client.CoreV1(), 60*time.Second, namespace) pluginCfg := templateplugin.TemplatePluginConfig{ - WorkingDir: workdir, - DefaultCertificateDir: workdir, - ReloadFn: func(shutdown bool) error { return nil }, - TemplatePath: "../../images/router/haproxy/conf/haproxy-config.template", - ReloadInterval: reloadInterval, + WorkingDir: workdir, + DefaultCertificateDir: workdir, + DefaultDestinationCAPath: defaultDestinationCA, + ReloadFn: func(shutdown bool) error { return nil }, + TemplatePath: "../../images/router/haproxy/conf/haproxy-config.template", + ReloadInterval: reloadInterval, HTTPResponseHeaders: []templateplugin.HTTPHeader{{ Name: "x-foo", Value: "'bar'", diff --git a/pkg/router/template/router.go b/pkg/router/template/router.go index fb61493c0..f9f1c7a26 100644 --- a/pkg/router/template/router.go +++ b/pkg/router/template/router.go @@ -281,6 +281,9 @@ func newTemplateRouter(cfg templateRouterCfg) (*templateRouter, error) { if err := router.watchMutualTLSCert(); err != nil { return nil, err } + if err := router.watchCABundleCert(); err != nil { + return nil, err + } if router.dynamicConfigManager != nil { log.V(0).Info("initializing dynamic config manager ... ") router.dynamicConfigManager.Initialize(router, router.defaultCertificatePath) @@ -1489,3 +1492,27 @@ func privateKeysFromPEM(pemCerts []byte) ([]byte, error) { } return buf.Bytes(), nil } + +// watchCABundleCert watches the directory containing the CA bundle certificate +// and reloads the router if the directory contents change. +func (r *templateRouter) watchCABundleCert() error { + caBundleDir := filepath.Dir(r.defaultDestinationCAPath) + + reloadFn := func() { + if err := r.reloadRouter(false); err != nil { + log.V(0).Error(err, "failed to reload router after detecting changes in CA bundle certificate directory") + return + } + log.V(0).Info("router was reloaded after detecting changes in CA bundle certificate directory") + } + + if err := r.watchVolumeMountDir(caBundleDir, reloadFn); err != nil { + // On encountering an error will log it and not return the error because + // DefaultDestinationCAPath is an optional configuration parameter, so an + // error here shouldn't cause router to exit. + log.V(0).Error(err, "failed to establish watch on CA bundle certificate directory") + return nil + } + + return nil +}