blob: 24b968e6b96b049dad87a77425825aaad05e2be9 [file] [log] [blame]
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package configutil
import (
"fmt"
"github.com/asaskevich/govalidator"
"github.com/hashicorp/go-secure-stdlib/strutil"
"github.com/hashicorp/hcl/hcl/token"
)
type UnusedKeyMap map[string][]token.Pos
type ConfigError struct {
Problem string
Position token.Pos
}
func (c *ConfigError) String() string {
return fmt.Sprintf("%s at %s", c.Problem, c.Position.String())
}
type ValidatableConfig interface {
Validate() []ConfigError
}
// Creates the ConfigErrors for unused fields, which occur in various structs
func ValidateUnusedFields(unusedKeyPositions UnusedKeyMap, sourceFilePath string) []ConfigError {
if unusedKeyPositions == nil {
return nil
}
var errors []ConfigError
for field, positions := range unusedKeyPositions {
problem := fmt.Sprintf("unknown or unsupported field %s found in configuration", field)
for _, pos := range positions {
if pos.Filename == "" && sourceFilePath != "" {
pos.Filename = sourceFilePath
}
errors = append(errors, ConfigError{
Problem: problem,
Position: pos,
})
}
}
return errors
}
// UnusedFieldDifference returns all the keys in map a that are not present in map b, and also not present in foundKeys.
func UnusedFieldDifference(a, b UnusedKeyMap, foundKeys []string) UnusedKeyMap {
if a == nil {
return nil
}
res := make(UnusedKeyMap)
for k, v := range a {
if _, ok := b[k]; !ok && !strutil.StrListContainsCaseInsensitive(foundKeys, govalidator.UnderscoreToCamelCase(k)) {
res[k] = v
}
}
return res
}