Restrict config file extensions read
This commit is contained in:
parent
bf1d799e3a
commit
66156e8f2f
|
@ -185,11 +185,13 @@ func (b *Builder) ReadPath(path string) ([]Source, error) {
|
|||
continue
|
||||
}
|
||||
|
||||
src, err := b.ReadFile(fp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if b.shouldParseFile(fp) {
|
||||
src, err := b.ReadFile(fp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sources = append(sources, src)
|
||||
}
|
||||
sources = append(sources, src)
|
||||
}
|
||||
return sources, nil
|
||||
}
|
||||
|
@ -204,6 +206,18 @@ func (b *Builder) ReadFile(path string) (Source, error) {
|
|||
return Source{Name: path, Data: string(data)}, nil
|
||||
}
|
||||
|
||||
// shouldParse file determines whether the file to be read is of a supported extension
|
||||
func (b *Builder) shouldParseFile(path string) bool {
|
||||
configFormat := b.stringVal(b.Flags.ConfigFormat)
|
||||
srcFormat := FormatFrom(path)
|
||||
|
||||
// If config-format is not set, only read files with supported extensions
|
||||
if configFormat == "" && srcFormat != "hcl" && srcFormat != "json" {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type byName []os.FileInfo
|
||||
|
||||
func (a byName) Len() int { return len(a) }
|
||||
|
@ -234,7 +248,6 @@ func (b *Builder) Build() (rt RuntimeConfig, err error) {
|
|||
// ----------------------------------------------------------------
|
||||
// merge config sources as follows
|
||||
//
|
||||
|
||||
configFormat := b.stringVal(b.Flags.ConfigFormat)
|
||||
if configFormat != "" && configFormat != "json" && configFormat != "hcl" {
|
||||
return RuntimeConfig{}, fmt.Errorf("config: -config-format must be either 'hcl' or 'json'")
|
||||
|
@ -244,23 +257,15 @@ func (b *Builder) Build() (rt RuntimeConfig, err error) {
|
|||
var srcs []Source
|
||||
srcs = append(srcs, b.Head...)
|
||||
for _, src := range b.Sources {
|
||||
// skip file if it should not be parsed
|
||||
if !b.shouldParseFile(src.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
// if config-format is set, files of any extension will be interpreted in that format
|
||||
src.Format = FormatFrom(src.Name)
|
||||
if configFormat != "" {
|
||||
src.Format = configFormat
|
||||
} else {
|
||||
// If they haven't forced things to a specific format,
|
||||
// then skip anything we don't understand, which is the
|
||||
// behavior before we added the -config-format option.
|
||||
switch src.Format {
|
||||
case "json", "hcl":
|
||||
// OK
|
||||
default:
|
||||
// SKIP
|
||||
continue
|
||||
}
|
||||
}
|
||||
if src.Format == "" {
|
||||
return RuntimeConfig{}, fmt.Errorf(`config: Missing or invalid file extension for %q. Please use ".json" or ".hcl".`, src.Name)
|
||||
}
|
||||
srcs = append(srcs, src)
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ func AddFlags(fs *flag.FlagSet, f *Flags) {
|
|||
add(&f.Config.BootstrapExpect, "bootstrap-expect", "Sets server to expect bootstrap mode.")
|
||||
add(&f.Config.ClientAddr, "client", "Sets the address to bind for client access. This includes RPC, DNS, HTTP, HTTPS and gRPC (if configured).")
|
||||
add(&f.ConfigFiles, "config-dir", "Path to a directory to read configuration files from. This will read every file ending in '.json' as configuration in this directory in alphabetical order. Can be specified multiple times.")
|
||||
add(&f.ConfigFiles, "config-file", "Path to a JSON file to read configuration from. Can be specified multiple times.")
|
||||
add(&f.ConfigFiles, "config-file", "Path to a file in JSON or HCL format with a matching file extension. Can be specified multiple times.")
|
||||
add(&f.ConfigFormat, "config-format", "Config files are in this format irrespective of their extension. Must be 'hcl' or 'json'")
|
||||
add(&f.Config.DataDir, "data-dir", "Path to a data directory to store agent state.")
|
||||
add(&f.Config.Datacenter, "datacenter", "Datacenter of the agent.")
|
||||
|
|
|
@ -5585,6 +5585,92 @@ func TestRuntime_ToTLSUtilConfig(t *testing.T) {
|
|||
require.Equal(t, c.EnableAgentTLSForChecks, r.EnableAgentTLSForChecks)
|
||||
}
|
||||
|
||||
func TestReadPath(t *testing.T) {
|
||||
dataDir := testutil.TempDir(t, "consul")
|
||||
defer os.RemoveAll(dataDir)
|
||||
|
||||
tt := []struct{
|
||||
name string
|
||||
pre func()
|
||||
args []string
|
||||
expect int
|
||||
}{
|
||||
{
|
||||
name: "dir skip non json or hcl if config-format not set",
|
||||
pre: func() {
|
||||
writeFile(filepath.Join(dataDir, "conf.d/conf.json"), []byte(`{}`))
|
||||
writeFile(filepath.Join(dataDir, "conf.d/conf.foobar"), []byte(`{}`))
|
||||
},
|
||||
args: []string{
|
||||
`-config-dir`, filepath.Join(dataDir, "conf.d"),
|
||||
},
|
||||
expect: 1,
|
||||
},
|
||||
{
|
||||
name: "dir read non json or hcl if config-format set",
|
||||
pre: func() {
|
||||
writeFile(filepath.Join(dataDir, "conf.d/conf.json"), []byte(`{}`))
|
||||
writeFile(filepath.Join(dataDir, "conf.d/conf.foobar"), []byte(`{}`))
|
||||
},
|
||||
args: []string{
|
||||
`-config-dir`, filepath.Join(dataDir, "conf.d"),
|
||||
`-config-format`, "json",
|
||||
},
|
||||
expect: 2,
|
||||
},
|
||||
{
|
||||
name: "file skip non json or hcl if config-format not set",
|
||||
pre: func() {
|
||||
writeFile(filepath.Join(dataDir, "conf.d/conf.foobar"), []byte(`{}`))
|
||||
},
|
||||
args: []string{
|
||||
`-config-file`, filepath.Join(dataDir, "conf.d"),
|
||||
},
|
||||
expect: 0,
|
||||
},
|
||||
{
|
||||
name: "file read non json or hcl if config-format set",
|
||||
pre: func() {
|
||||
writeFile(filepath.Join(dataDir, "conf.d/conf.foobar"), []byte(`{}`))
|
||||
},
|
||||
args: []string{
|
||||
`-config-file`, filepath.Join(dataDir, "conf.d"),
|
||||
`-config-format`, "json",
|
||||
},
|
||||
expect: 1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tt {
|
||||
cleanDir(dataDir)
|
||||
|
||||
t.Run(tc.name, func(t * testing.T) {
|
||||
flags := Flags{}
|
||||
fs := flag.NewFlagSet("", flag.ContinueOnError)
|
||||
AddFlags(fs, &flags)
|
||||
err := fs.Parse(tc.args)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseFlags failed: %s", err)
|
||||
}
|
||||
flags.Args = fs.Args()
|
||||
|
||||
// write cfg files
|
||||
tc.pre()
|
||||
|
||||
// Then create a builder with the flags.
|
||||
b, err := NewBuilder(flags)
|
||||
if err != nil {
|
||||
t.Fatal("NewBuilder", err)
|
||||
}
|
||||
|
||||
got := len(b.Sources)
|
||||
if tc.expect != got {
|
||||
t.Fatalf("expected %d sources, got %d", tc.expect, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func splitIPPort(hostport string) (net.IP, int) {
|
||||
h, p, err := net.SplitHostPort(hostport)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue