Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pre merge validation #563

Merged
merged 19 commits into from
Aug 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Unreleased changes are available as `avenga/couper:edge` container.
* **Fixed**
* Disallow empty path parameters ([#526](https://github.com/avenga/couper/pull/526))
* Basic Auth client authentication with OAuth2 (client ID and secret must be URL encoded) ([#537](https://github.com/avenga/couper/pull/537))
* Config validation, e.g. label-uniqueness checks ([#563](https://github.com/avenga/couper/pull/563))

* **Removed**
* Endpoint path normalization to better match OpenAPI behavior ([#526](https://github.com/avenga/couper/pull/526))
Expand Down
13 changes: 3 additions & 10 deletions config/configload/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,7 @@ func PrepareBackend(helper *helper, attrName, attrValue string, block config.Inl
backendBody = hclbody.MergeBodies(defaultBackend, backendBody)
}

backendBody, err = newBodyWithName(anonLabel, backendBody)
if err != nil {
return nil, err
}
backendBody = newBodyWithName(anonLabel, backendBody)
}

// watch out for oauth blocks and nested backend definitions
Expand Down Expand Up @@ -255,15 +252,11 @@ func newBlock(blockType string, content hcl.Body) hcl.Body {
})
}

func newBodyWithName(nameValue string, config hcl.Body) (hcl.Body, error) {
if err := validLabel(nameValue, getRange(config)); err != nil {
return nil, err
}

func newBodyWithName(nameValue string, config hcl.Body) hcl.Body {
return hclbody.MergeBodies(
config,
hclbody.New(hclbody.NewContentWithAttrName("name", nameValue)),
), nil
)
}

func newAnonLabel(body hcl.Body, labelRange *hcl.Range) string {
Expand Down
4 changes: 2 additions & 2 deletions config/configload/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ func preprocessBody(body *hclsyntax.Body, env string) (bool, error) {
return true, newDiagErr(&defRange, "Missing label(s) for 'environment' block")
}

for _, label := range block.Labels {
if err := validLabel(label, getRange(block.Body)); err != nil {
for i, label := range block.Labels {
if err := validLabel(label, &block.LabelRanges[i]); err != nil {
return true, err
}

Expand Down
16 changes: 2 additions & 14 deletions config/configload/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,12 @@ func newHelper(body hcl.Body, src [][]byte, environment string) (*helper, error)
}, nil
}

func (h *helper) addBackend(block *hcl.Block) error {
func (h *helper) addBackend(block *hcl.Block) {
name := block.Labels[0]

if _, ok := h.defsBackends[name]; ok {
return newDiagErr(&block.LabelRanges[0],
fmt.Sprintf("duplicate backend name: %q", name))
} else if strings.HasPrefix(name, "anonymous_") {
return newDiagErr(&block.LabelRanges[0],
fmt.Sprintf("backend name must not start with 'anonymous_': %q", name))
}

backendBody, err := newBodyWithName(name, block.Body)
if err != nil {
return err
}
backendBody := newBodyWithName(name, block.Body)

h.defsBackends[name] = backendBody
return nil
}

func (h *helper) configureDefinedBackends() error {
Expand Down
118 changes: 77 additions & 41 deletions config/configload/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,38 +128,7 @@ func parseFiles(files configfile.Files) ([]*hclsyntax.Body, [][]byte, error) {
return parsedBodies, srcBytes, nil
}

func LoadFiles(filesList []string, env string) (*config.Couper, error) {
configFiles, err := configfile.NewFiles(filesList)
if err != nil {
return nil, err
}

parsedBodies, srcBytes, err := parseFiles(configFiles)
if err != nil {
return nil, err
}

if len(srcBytes) == 0 {
return nil, fmt.Errorf("missing configuration files")
}

errorBeforeRetry := preprocessEnvironmentBlocks(parsedBodies, env)

if env == "" {
settingsBlock := mergeSettings(parsedBodies)
settings := &config.Settings{}
if diags := gohcl.DecodeBody(settingsBlock.Body, nil, settings); diags.HasErrors() {
return nil, diags
}
if settings.Environment != "" {
return LoadFiles(filesList, settings.Environment)
}
}

if errorBeforeRetry != nil {
return nil, errorBeforeRetry
}

func bodiesToConfig(parsedBodies []*hclsyntax.Body, srcBytes [][]byte, env string) (*config.Couper, error) {
defaultsBlock, err := mergeDefaults(parsedBodies)
if err != nil {
return nil, err
Expand All @@ -177,6 +146,10 @@ func LoadFiles(filesList []string, env string) (*config.Couper, error) {
if err = absolutizePaths(body); err != nil {
return nil, err
}

if err = validateBody(body, false); err != nil {
return nil, err
}
}

settingsBlock := mergeSettings(parsedBodies)
Expand All @@ -200,11 +173,54 @@ func LoadFiles(filesList []string, env string) (*config.Couper, error) {
Blocks: configBlocks,
}

if err = validateBody(configBody, true); err != nil {
return nil, err
}

conf, err := LoadConfig(configBody, srcBytes, env)
if err != nil {
return nil, err
}

return conf, nil
}

func LoadFiles(filesList []string, env string) (*config.Couper, error) {
configFiles, err := configfile.NewFiles(filesList)
if err != nil {
return nil, err
}

parsedBodies, srcBytes, err := parseFiles(configFiles)
if err != nil {
return nil, err
}

if len(srcBytes) == 0 {
return nil, fmt.Errorf("missing configuration files")
}

errorBeforeRetry := preprocessEnvironmentBlocks(parsedBodies, env)

if env == "" {
settingsBlock := mergeSettings(parsedBodies)
settings := &config.Settings{}
if diags := gohcl.DecodeBody(settingsBlock.Body, nil, settings); diags.HasErrors() {
return nil, diags
}
if settings.Environment != "" {
return LoadFiles(filesList, settings.Environment)
}
}

if errorBeforeRetry != nil {
return nil, errorBeforeRetry
}

conf, err := bodiesToConfig(parsedBodies, srcBytes, env)
if err != nil {
return nil, err
}
conf.Files = configFiles

return conf, nil
Expand All @@ -214,12 +230,40 @@ func LoadFile(file, env string) (*config.Couper, error) {
return LoadFiles([]string{file}, env)
}

type testContent struct {
filename string
src []byte
}

func loadTestContents(tcs []testContent) (*config.Couper, error) {
var (
parsedBodies []*hclsyntax.Body
srcs [][]byte
)

for _, tc := range tcs {
hclBody, diags := parser.Load(tc.src, tc.filename)
if diags.HasErrors() {
return nil, diags
}

parsedBodies = append(parsedBodies, hclBody.(*hclsyntax.Body))
srcs = append(srcs, tc.src)
}

return bodiesToConfig(parsedBodies, srcs, "")
}

func LoadBytes(src []byte, filename string) (*config.Couper, error) {
hclBody, diags := parser.Load(src, filename)
if diags.HasErrors() {
return nil, diags
}

if err := validateBody(hclBody, false); err != nil {
return nil, err
}

return LoadConfig(hclBody, [][]byte{src}, "")
}

Expand All @@ -246,9 +290,7 @@ func LoadConfig(body hcl.Body, src [][]byte, environment string) (*config.Couper
// backends first
if backendContent != nil {
for _, be := range backendContent.Blocks {
if err = helper.addBackend(be); err != nil {
return nil, err
}
helper.addBackend(be)
}

if err = helper.configureDefinedBackends(); err != nil {
Expand Down Expand Up @@ -316,9 +358,6 @@ func LoadConfig(body hcl.Body, src [][]byte, environment string) (*config.Couper

jwtSigningConfigs := make(map[string]*lib.JWTSigningConfig)
for _, profile := range helper.config.Definitions.JWTSigningProfile {
if _, exists := jwtSigningConfigs[profile.Name]; exists {
return nil, errors.Configuration.Messagef("jwt_signing_profile block with label %s already defined", profile.Name)
}
signConf, err := lib.NewJWTSigningConfigFromJWTSigningProfile(profile)
if err != nil {
return nil, errors.Configuration.Label(profile.Name).With(err)
Expand All @@ -331,9 +370,6 @@ func LoadConfig(body hcl.Body, src [][]byte, environment string) (*config.Couper
return nil, errors.Configuration.Label(jwt.Name).With(err)
}
if signConf != nil {
if _, exists := jwtSigningConfigs[jwt.Name]; exists {
return nil, errors.Configuration.Messagef("jwt_signing_profile or jwt with label %s already defined", jwt.Name)
}
jwtSigningConfigs[jwt.Name] = signConf
}
}
Expand Down
4 changes: 0 additions & 4 deletions config/configload/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,10 +415,6 @@ func mergeDefinitions(bodies []*hclsyntax.Body) (*hclsyntax.Block, error) {
definitionsBlock[innerBlock.Type] = make(data)
}

if len(innerBlock.Labels) == 0 {
return nil, newMergeError(errUniqueLabels, innerBlock)
}

definitionsBlock[innerBlock.Type][innerBlock.Labels[0]] = innerBlock

// Count the "backend" blocks and "backend" attributes to
Expand Down
Loading