feat: use parser to load dynamic config from file.
This commit is contained in:
parent
7affeae480
commit
cb1d0441e9
27 changed files with 187 additions and 88 deletions
|
@ -2,7 +2,11 @@
|
|||
package file
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/containous/traefik/v2/pkg/config/parser"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// Decode decodes the given configuration file into the given element.
|
||||
|
@ -22,11 +26,57 @@ func Decode(filePath string, element interface{}) error {
|
|||
return err
|
||||
}
|
||||
|
||||
metaOpts := parser.MetadataOpts{TagName: parser.TagLabel, AllowSliceAsStruct: true}
|
||||
metaOpts := parser.MetadataOpts{TagName: parser.TagFile, AllowSliceAsStruct: false}
|
||||
err = parser.AddMetadata(element, root, metaOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return parser.Fill(element, root, parser.FillerOpts{AllowSliceAsStruct: true})
|
||||
return parser.Fill(element, root, parser.FillerOpts{AllowSliceAsStruct: false})
|
||||
}
|
||||
|
||||
// DecodeContent decodes the given configuration file content into the given element.
|
||||
// The operation goes through three stages roughly summarized as:
|
||||
// file contents -> tree of untyped nodes
|
||||
// untyped nodes -> nodes augmented with metadata such as kind (inferred from element)
|
||||
// "typed" nodes -> typed element.
|
||||
func DecodeContent(content string, extension string, element interface{}) error {
|
||||
data := make(map[string]interface{})
|
||||
|
||||
switch extension {
|
||||
case ".toml":
|
||||
_, err := toml.Decode(content, &data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case ".yml", ".yaml":
|
||||
var err error
|
||||
err = yaml.Unmarshal([]byte(content), &data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unsupported file extension: %s", extension)
|
||||
}
|
||||
|
||||
filters := getRootFieldNames(element)
|
||||
|
||||
node, err := decodeRawToNode(data, parser.DefaultRootName, filters...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(node.Children) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
metaOpts := parser.MetadataOpts{TagName: parser.TagFile, AllowSliceAsStruct: false}
|
||||
err = parser.AddMetadata(element, node, metaOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return parser.Fill(element, node, parser.FillerOpts{AllowSliceAsStruct: false})
|
||||
}
|
||||
|
|
|
@ -42,6 +42,32 @@ fii = "bir"
|
|||
assert.Equal(t, expected, element)
|
||||
}
|
||||
|
||||
func TestDecodeContent_TOML(t *testing.T) {
|
||||
content := `
|
||||
foo = "bar"
|
||||
fii = "bir"
|
||||
[yi]
|
||||
`
|
||||
|
||||
element := &Yo{
|
||||
Fuu: "test",
|
||||
}
|
||||
|
||||
err := DecodeContent(content, ".toml", element)
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := &Yo{
|
||||
Foo: "bar",
|
||||
Fii: "bir",
|
||||
Fuu: "test",
|
||||
Yi: &Yi{
|
||||
Foo: "foo",
|
||||
Fii: "fii",
|
||||
},
|
||||
}
|
||||
assert.Equal(t, expected, element)
|
||||
}
|
||||
|
||||
func TestDecode_YAML(t *testing.T) {
|
||||
f, err := ioutil.TempFile("", "traefik-config-*.yaml")
|
||||
require.NoError(t, err)
|
||||
|
@ -74,3 +100,29 @@ yi: {}
|
|||
}
|
||||
assert.Equal(t, expected, element)
|
||||
}
|
||||
|
||||
func TestDecodeContent_YAML(t *testing.T) {
|
||||
content := `
|
||||
foo: bar
|
||||
fii: bir
|
||||
yi: {}
|
||||
`
|
||||
|
||||
element := &Yo{
|
||||
Fuu: "test",
|
||||
}
|
||||
|
||||
err := DecodeContent(content, ".yaml", element)
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := &Yo{
|
||||
Foo: "bar",
|
||||
Fii: "bir",
|
||||
Fuu: "test",
|
||||
Yi: &Yi{
|
||||
Foo: "foo",
|
||||
Fii: "fii",
|
||||
},
|
||||
}
|
||||
assert.Equal(t, expected, element)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ type Yo struct {
|
|||
Foo string
|
||||
Fii string
|
||||
Fuu string
|
||||
Yi *Yi `label:"allowEmpty"`
|
||||
Yi *Yi `file:"allowEmpty"`
|
||||
}
|
||||
|
||||
func (y *Yo) SetDefaults() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue