From 5e33e83a841ef4f9468365d5c094719396a62f73 Mon Sep 17 00:00:00 2001 From: Alexander Vollschwitz Date: Mon, 14 Mar 2022 13:32:41 +0100 Subject: [PATCH] support for protecting plugin prameters (#308) --- config-reloader/fluentd/parser.go | 27 +++++++++++++------ config-reloader/fluentd/parser_test.go | 16 +++++++++++ config-reloader/processors/extract_plugins.go | 4 +-- .../processors/extract_plugins_test.go | 10 +++++++ 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/config-reloader/fluentd/parser.go b/config-reloader/fluentd/parser.go index 0722485e..66861f48 100644 --- a/config-reloader/fluentd/parser.go +++ b/config-reloader/fluentd/parser.go @@ -43,8 +43,9 @@ type Directive struct { // Param just holds a Name/Value pair type Param struct { - Name string - Value string + Name string + Value string + Protected bool } // Type return the @type parameter or type parameter. "" if not type is defined @@ -89,8 +90,9 @@ func (d *Directive) Clone() *Directive { func (p *Param) Clone() *Param { return &Param{ - Name: p.Name, - Value: p.Value, + Name: p.Name, + Value: p.Value, + Protected: p.Protected, } } @@ -115,10 +117,11 @@ func ParamsFromKV(keyValues ...string) Params { k := keyValues[i] v := keyValues[i+1] - res[k] = &Param{ + p := protect(&Param{ Name: k, Value: v, - } + }) + res[p.Name] = p } return res @@ -288,9 +291,9 @@ func ParseString(s string) (Fragment, error) { p := reParam.FindStringSubmatch(line) if len(p) > 0 { - param := &Param{ + param := protect(&Param{ Name: p[1], - } + }) if len(p) > 2 { param.Value = p[3] // special handling for @type as it is processed @@ -315,3 +318,11 @@ func ParseString(s string) (Fragment, error) { return res, nil } + +func protect(p *Param) *Param { + if p != nil && !p.Protected && strings.HasPrefix(p.Name, "!") { + p.Name = p.Name[1:] + p.Protected = true + } + return p +} diff --git a/config-reloader/fluentd/parser_test.go b/config-reloader/fluentd/parser_test.go index dd1b73e6..afc6ef7d 100644 --- a/config-reloader/fluentd/parser_test.go +++ b/config-reloader/fluentd/parser_test.go @@ -219,3 +219,19 @@ func TestParseNested(t *testing.T) { assert.Equal(t, "file", match.Type()) assert.Equal(t, "/var/log/fluent/access", match.Param("path")) } + +func TestProtectedParam(t *testing.T) { + dir := Directive{ + Name: "ok", + Tag: "tag", + Params: ParamsFromKV("a", "1", "!b", "2"), + } + + assert.Equal(t, 2, len(dir.Params)) + assert.False(t, dir.Params["a"].Protected) + assert.True(t, dir.Params["b"].Protected) + + params := dir.Params.Clone() + assert.False(t, params["a"].Protected) + assert.True(t, params["b"].Protected) +} diff --git a/config-reloader/processors/extract_plugins.go b/config-reloader/processors/extract_plugins.go index f149e987..0b0a361b 100644 --- a/config-reloader/processors/extract_plugins.go +++ b/config-reloader/processors/extract_plugins.go @@ -55,8 +55,8 @@ func (p *expandPluginsState) Process(input fluentd.Fragment) (fluentd.Fragment, // replace the params for k, v := range replacement.Params { - // prefer the params defined at the call site - if _, ok := d.Params[k]; !ok { + // prefer the params defined at the call site, unless the param is protected + if _, ok := d.Params[k]; !ok || v.Protected { d.Params[k] = v.Clone() } } diff --git a/config-reloader/processors/extract_plugins_test.go b/config-reloader/processors/extract_plugins_test.go index 662b38d2..aac1daf6 100644 --- a/config-reloader/processors/extract_plugins_test.go +++ b/config-reloader/processors/extract_plugins_test.go @@ -41,6 +41,8 @@ func TestExpandPlugins(t *testing.T) { username admin buffer_path /hello/world buffer_size 1m + !fixed DoNotChange + !keep KeepIt @type file path /var/log/fluentd.*.buffer @@ -72,6 +74,10 @@ func TestExpandPlugins(t *testing.T) { # param is overridden buffer_size 5m + + # params are protected + fixed Changed + !keep Changed @@ -107,6 +113,10 @@ func TestExpandPlugins(t *testing.T) { // param that's overridden assert.Equal(t, "5m", matchDir.Param("buffer_size")) + // params that are protected should remain unchanged + assert.Equal(t, "DoNotChange", matchDir.Param("fixed")) + assert.Equal(t, "KeepIt", matchDir.Param("keep")) + // nested content is present assert.Equal(t, "buffer", matchDir.Nested[0].Name) assert.Equal(t, "/var/log/fluentd.*.buffer", matchDir.Nested[0].Param("path"))