| // 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 |
| } |