Skip to content

Commit 895054c

Browse files
[proxy] add experimental flag let configcat proxy always serve config from configmap (#17095)
* [proxy] add experimental flag let configcat proxy always serve config from configmap * use etag * Update components/proxy/plugins/configcat/configcat.go Co-authored-by: Filip Troníček <[email protected]> * Fix warnings and add a notice * use `CONFIGCAT_DIR` --------- Co-authored-by: Filip Troníček <[email protected]>
1 parent 2468e38 commit 895054c

File tree

5 files changed

+83
-18
lines changed

5 files changed

+83
-18
lines changed

components/proxy/plugins/configcat/configcat.go

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"io/ioutil"
1010
"net/http"
1111
"os"
12+
"path"
1213
"regexp"
1314
"strings"
1415
"sync"
@@ -49,6 +50,8 @@ type ConfigCat struct {
4950
// pollInterval sets after how much time a configuration is considered stale.
5051
pollInterval time.Duration
5152

53+
configCatConfigDir string
54+
5255
configCache map[string]*configCache
5356
m sync.RWMutex
5457

@@ -64,19 +67,44 @@ func (ConfigCat) CaddyModule() caddy.ModuleInfo {
6467
}
6568
}
6669

70+
func (c *ConfigCat) ServeFromFile(w http.ResponseWriter, r *http.Request, fileName string) {
71+
fp := path.Join(c.configCatConfigDir, fileName)
72+
d, err := os.Stat(fp)
73+
if err != nil {
74+
// This should only happen before deploying the FF resource, and logging would not be helpful, hence we can fallback to the default values.
75+
_, _ = w.Write(DefaultConfig)
76+
return
77+
}
78+
requestEtag := r.Header.Get("If-None-Match")
79+
etag := fmt.Sprintf(`W/"%x-%x"`, d.ModTime().Unix(), d.Size())
80+
if requestEtag != "" && requestEtag == etag {
81+
w.WriteHeader(http.StatusNotModified)
82+
return
83+
}
84+
w.Header().Set("ETag", etag)
85+
http.ServeFile(w, r, fp)
86+
}
87+
6788
// ServeHTTP implements caddyhttp.MiddlewareHandler.
6889
func (c *ConfigCat) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
6990
if !pathRegex.MatchString(r.URL.Path) {
7091
return next.ServeHTTP(w, r)
7192
}
93+
arr := strings.Split(r.URL.Path, "/")
94+
configVersion := arr[len(arr)-1]
95+
96+
if c.configCatConfigDir != "" {
97+
c.ServeFromFile(w, r, configVersion)
98+
return nil
99+
}
100+
72101
w.Header().Set("Content-Type", "application/json")
73102
if c.sdkKey == "" {
74-
w.Write(DefaultConfig)
103+
_, _ = w.Write(DefaultConfig)
75104
return nil
76105
}
77106
etag := r.Header.Get("If-None-Match")
78-
arr := strings.Split(r.URL.Path, "/")
79-
configVersion := arr[len(arr)-1]
107+
80108
config := c.getConfigWithCache(configVersion)
81109
if etag != "" && config.hash == etag {
82110
w.WriteHeader(http.StatusNotModified)
@@ -94,9 +122,14 @@ func (c *ConfigCat) Provision(ctx caddy.Context) error {
94122
c.configCache = make(map[string]*configCache)
95123

96124
c.sdkKey = os.Getenv("CONFIGCAT_SDK_KEY")
125+
c.configCatConfigDir = os.Getenv("CONFIGCAT_DIR")
97126
if c.sdkKey == "" {
98127
return nil
99128
}
129+
if c.configCatConfigDir != "" {
130+
c.logger.Info("serving configcat configuration from local directory")
131+
return nil
132+
}
100133

101134
c.httpClient = &http.Client{
102135
Timeout: 10 * time.Second,

install/installer/pkg/common/common.go

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -435,9 +435,10 @@ func ConfigcatEnv(ctx *RenderContext) []corev1.EnvVar {
435435

436436
func ConfigcatProxyEnv(ctx *RenderContext) []corev1.EnvVar {
437437
var (
438-
sdkKey string
439-
baseUrl string
440-
pollInterval string
438+
sdkKey string
439+
baseUrl string
440+
pollInterval string
441+
fromConfigMap string
441442
)
442443
_ = ctx.WithExperimental(func(cfg *experimental.Config) error {
443444
if cfg.WebApp != nil && cfg.WebApp.ConfigcatKey != "" {
@@ -446,28 +447,42 @@ func ConfigcatProxyEnv(ctx *RenderContext) []corev1.EnvVar {
446447
if cfg.WebApp != nil && cfg.WebApp.ProxyConfig != nil && cfg.WebApp.ProxyConfig.Configcat != nil {
447448
baseUrl = cfg.WebApp.ProxyConfig.Configcat.BaseUrl
448449
pollInterval = cfg.WebApp.ProxyConfig.Configcat.PollInterval
450+
fromConfigMap = cfg.WebApp.ProxyConfig.Configcat.FromConfigMap
449451
}
450452
return nil
451453
})
452454

453455
if sdkKey == "" {
454456
return nil
455457
}
456-
457-
return []corev1.EnvVar{
458+
envs := []corev1.EnvVar{
458459
{
459460
Name: "CONFIGCAT_SDK_KEY",
460461
Value: sdkKey,
461462
},
462-
{
463-
Name: "CONFIGCAT_BASE_URL",
464-
Value: baseUrl,
465-
},
466-
{
467-
Name: "CONFIGCAT_POLL_INTERVAL",
468-
Value: pollInterval,
469-
},
470463
}
464+
465+
if fromConfigMap != "" {
466+
envs = append(envs,
467+
corev1.EnvVar{
468+
Name: "CONFIGCAT_DIR",
469+
Value: "/data/configcat/",
470+
},
471+
)
472+
} else {
473+
envs = append(envs,
474+
corev1.EnvVar{
475+
Name: "CONFIGCAT_BASE_URL",
476+
Value: baseUrl,
477+
},
478+
corev1.EnvVar{
479+
Name: "CONFIGCAT_POLL_INTERVAL",
480+
Value: pollInterval,
481+
},
482+
)
483+
}
484+
485+
return envs
471486
}
472487

473488
func DatabaseWaiterContainer(ctx *RenderContext) *corev1.Container {

install/installer/pkg/components/proxy/deployment.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,21 @@ func deployment(ctx *common.RenderContext) ([]runtime.Object, error) {
103103
if cfg.WebApp != nil && cfg.WebApp.ProxyConfig != nil {
104104
frontendDevEnabled = cfg.WebApp.ProxyConfig.FrontendDevEnabled
105105
}
106+
if cfg.WebApp != nil && cfg.WebApp.ProxyConfig != nil && cfg.WebApp.ProxyConfig.Configcat != nil && cfg.WebApp.ProxyConfig.Configcat.FromConfigMap != "" {
107+
volumes = append(volumes, corev1.Volume{
108+
Name: "configcat",
109+
VolumeSource: corev1.VolumeSource{
110+
ConfigMap: &corev1.ConfigMapVolumeSource{
111+
LocalObjectReference: corev1.LocalObjectReference{Name: cfg.WebApp.ProxyConfig.Configcat.FromConfigMap},
112+
Optional: pointer.Bool(true),
113+
},
114+
},
115+
})
116+
volumeMounts = append(volumeMounts, corev1.VolumeMount{
117+
Name: "configcat",
118+
MountPath: "/data/configcat",
119+
})
120+
}
106121
return nil
107122
})
108123

install/installer/pkg/config/v1/config.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ Additional config parameters that are in experimental state
147147
|`experimental.webapp.proxy.serviceType`||N| | @deprecated use components.proxy.service.serviceType instead|
148148
|`experimental.webapp.proxy.configcat.baseUrl`|string|N| ||
149149
|`experimental.webapp.proxy.configcat.pollInterval`|string|N| ||
150+
|`experimental.webapp.proxy.configcat.fromConfigMap`|string|N| ||
150151
|`experimental.webapp.wsManagerBridge.skipSelf`|bool|N| ||
151152
|`experimental.webapp.tracing.samplerType`|string|N| `const`, `probabilistic`, `rateLimiting`, `remote` |Values taken from https://github.com/jaegertracing/jaeger-client-go/blob/967f9c36f0fa5a2617c9a0993b03f9a3279fadc8/config/config.go#L71|
152153
|`experimental.webapp.tracing.samplerParam`|float64|N| ||

install/installer/pkg/config/v1/experimental/experimental.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,9 @@ type ProxyConfig struct {
287287
}
288288

289289
type ConfigcatProxyConfig struct {
290-
BaseUrl string `json:"baseUrl"`
291-
PollInterval string `json:"pollInterval"`
290+
BaseUrl string `json:"baseUrl"`
291+
PollInterval string `json:"pollInterval"`
292+
FromConfigMap string `json:"fromConfigMap"`
292293
}
293294

294295
type PublicAPIConfig struct {

0 commit comments

Comments
 (0)