deckhouse / deckhouse/deckhouse

[openapi] empty default should not be specified for required objects with required properties

Open
#2,987 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area/testing priority/backlog source/deckhouse-team
Dominant language
Go
Stars
1.3k
Forks
162
Avg merge
1d 5h
Merged PRs (30d)
653

Description

Preflight Checklist
  • I agree to follow the Code of Conduct that this project adheres to.
  • I have searched the issue tracker for an issue that matches the one I want to file, without success.
Version

main

Affected modules
  required: ["addressPools"]
...
  addressPools:
    type: array
    default: []
required:
  - auth
...
  auth:
    type: object
    default: {}
Expected Behavior

OpenAPI cases test should not fail for this setup:

MODULE/openapi/values.yaml

type: object
properties:
  internal:
    type: object
    required:
    - someCert
    properties:
      nonRequired:
        type: string
      cert:
        type: object
        default: {}
        required:
          - ca
          - crt
          - key
        properties:
          ca:
            type: string
            x-examples: ["YjY0ZW5jX3N0cmluZwo="]
          crt:
            type: string
            x-examples: [ "YjY0ZW5jX3N0cmluZwo=" ]
          key:
            type: string
            x-examples: [ "YjY0ZW5jX3N0cmluZwo=" ]        

MODULE/openapi/openapi-case-tests.yaml

negative:
  values:
  - internal:
      nonRequired: "some-value"
Actual Behavior

make test-openapi fails because negative case validates successfully.

Steps To Reproduce

No response

Additional Information

The root cause is using default:{} and required for required object. We think it is a valid schema, and JSON schema spec tells us it is:

The default keyword specifies a default value. This value is not used to fill in missing values during the validation process.
Source: JSON Schema spec/Generic keywords

And here is the implementation of the "validation process" in go-openapi/validate:

	createdFromDefaults := map[string]bool{}

	// Property types:
	// - regular Property
	for pName := range o.Properties {
		...

		// Recursively validates each property against its schema
		if v, ok := val[pName]; ok {
			...
		} else if pSchema.Default != nil {
			// If a default value is defined, creates the property from defaults
			// NOTE: JSON schema does not enforce default values to be valid against schema. Swagger does.
			createdFromDefaults[pName] = true
			...
		}
	}

	// Check required properties
	if len(o.Required) > 0 {
		for _, k := range o.Required {
IT IS OK IF REQUIRED FIELD IS NOT SPECIFIED BUT HAS DEFAULT
-----------------------------------------------------v
			if v, ok := val[k]; !ok && !createdFromDefaults[k] {
				res.AddErrors(errors.Required(o.Path+"."+k, o.In, v))
				continue
			}
		}
	}

Source: go-openapi/validate/object_validator.go

It seems we need to remove default: {} from all required certs and other such properties.

Logs

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with make test-openapi and the OpenAPI case tests, then inspect the affected config-values.yaml files in 380-metallb and 500-upmeter and the values/openapi-case-tests.yaml example. Compare required-object handling with go-openapi/validate/object_validator.go. Done means the negative case remains invalid while valid defaults continue to work and make test-openapi passes.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, openapi
Domain
api, testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.