Skip to content

Commit

Permalink
disallow unknown fields (#98)
Browse files Browse the repository at this point in the history
* disallow unknown fields

* test ci
  • Loading branch information
nicolasparada authored Jun 24, 2024
1 parent 8ad01f1 commit c50f035
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 7 deletions.
36 changes: 33 additions & 3 deletions dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"errors"
"io"
"strings"

"gopkg.in/yaml.v3"
Expand All @@ -23,15 +24,44 @@ func ParseAs(raw string, format Format) (Config, error) {
var out Config
switch strings.ToLower(string(format)) {
case "", "ini", "conf", "classic":
return out, out.UnmarshalClassic([]byte(raw))
return ParseAsClassic(raw)
case "yml", "yaml":
return out, yaml.Unmarshal([]byte(raw), &out)
return ParseAsYAML(raw)
case "json":
return out, json.Unmarshal([]byte(raw), &out)
return ParseAsJSON(raw)
}
return out, ErrFormatUnknown
}

func ParseAsClassic(raw string) (Config, error) {
var out Config
return out, out.UnmarshalClassic([]byte(raw))
}

func ParseAsYAML(raw string) (Config, error) {
var out Config
dec := yaml.NewDecoder(strings.NewReader(raw))
dec.KnownFields(true)
err := dec.Decode(&out)
if errors.Is(err, io.EOF) {
return out, nil
}

return out, err
}

func ParseAsJSON(raw string) (Config, error) {
var out Config
dec := json.NewDecoder(strings.NewReader(raw))
dec.DisallowUnknownFields()
err := dec.Decode(&out)
if errors.Is(err, io.EOF) {
return out, nil
}

return out, err
}

func (c Config) DumpAs(format Format) (string, error) {
switch strings.ToLower(string(format)) {
case "", "ini", "conf", "classic":
Expand Down
80 changes: 80 additions & 0 deletions dump_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package fluentbitconfig

import (
"fmt"
"strings"
"testing"

"github.com/alecthomas/assert/v2"
"github.com/muesli/reflow/dedent"

"github.com/calyptia/go-fluentbit-config/v2/property"
)

func TestParseAsYAML(t *testing.T) {
t.Run("unknown_plural_pipelines", func(t *testing.T) {
_, err := ParseAsYAML(configLiteral(`
pipelines:
inputs:
- name: dummy
`))
assert.EqualError(t, err, "yaml: unmarshal errors:\n line 1: field pipelines not found in type fluentbitconfig.Config")
})

t.Run("unknown_section", func(t *testing.T) {
_, err := ParseAsYAML(configLiteral(`
unknown:
- name: dummy
`))
assert.EqualError(t, err, "yaml: unmarshal errors:\n line 1: field unknown not found in type fluentbitconfig.Config")
})

t.Run("unknown_pipeline_plugins_kind", func(t *testing.T) {
_, err := ParseAsYAML(configLiteral(`
pipeline:
foos:
- name: bar
`))
assert.EqualError(t, err, "yaml: unmarshal errors:\n line 2: field foos not found in type fluentbitconfig.Pipeline")
})

t.Run("empty", func(t *testing.T) {
got, err := ParseAsYAML("")
assert.NoError(t, err)
assert.Equal(t, Config{}, got)
})

t.Run("ok", func(t *testing.T) {
text := configLiteral(`
pipeline:
inputs:
- name: dummy
`)
fmt.Printf("text: %q\n", text)
cfg, err := ParseAsYAML(text)
assert.NoError(t, err)
assert.Equal(t, Config{
Pipeline: Pipeline{
Inputs: []Plugin{
{
ID: "dummy.0",
Name: "dummy",
Properties: property.Properties{
{
Key: "name",
Value: "dummy",
},
},
},
},
},
}, cfg)
})
}

func configLiteral(s string) string {
if strings.HasPrefix(s, "\n\t") {
s = dedent.String(s)
}
return strings.TrimSpace(strings.ReplaceAll(s, "\t", " ")) + "\n"
}
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ go 1.22.4

require (
github.com/alecthomas/assert/v2 v2.10.0
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8
github.com/muesli/reflow v0.3.0
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8
gopkg.in/yaml.v3 v3.0.1
)

Expand Down
10 changes: 7 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM=
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

0 comments on commit c50f035

Please sign in to comment.