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

Regression: fails to invalidate correct schema with an object field named type #601

Closed
thediveo opened this issue Sep 18, 2022 · 2 comments · Fixed by #602
Closed

Regression: fails to invalidate correct schema with an object field named type #601

thediveo opened this issue Sep 18, 2022 · 2 comments · Fixed by #602

Comments

@thediveo
Copy link

thediveo commented Sep 18, 2022

Upgrading from v0.94.0 to v0.102.0 I'm seeing a regression where kin-openapi fails to validate a schema that was formerly valid. To back up my claim, https://apitools.dev/swagger-parser/online/ also properly validates my schema. The full schema is https://github.com/thediveo/lxkns/blob/master/api/openapi-spec/lxkns.yaml.

Following is an element where v0.102.0 chokes:

components:
    schemas:
        Namespace:
            description: |-
                Information about a single Linux-kernel namespace. Depending on the extent of
                the discovery, not all namespace types might have been discovered, or data might
                be missing about the PID and user namespace hierarchies as well as which user
                namespace owns other namespaces.

                For more details, please see also:
                https://man7.org/linux/man-pages/man7/namespaces.7.html.
            required:
                - type
                - nsid
            type: object
            properties:
                nsid:
                    format: int64
                    description: |-
                        Identifier of this namespace: an inode number.

                        - lxkns only uses the inode number in the API, following current Linux kernel
                          and CLI tool practise, which generally identify individual namespaces only by
                          inode numbers (and leaving out the device number).
                        - Namespace identifiers are not UUIDs, but instead reused by the kernel after a
                          namespace has been destroyed.
                    type: integer
                type:
                    $ref: '#/components/schemas/NamespaceType'
                    description: Type of this namespace.
                owner:
                    format: int64
                    description: The ID of the owning user namespace.
                    type: integer
fenollp added a commit to fenollp/kin-openapi that referenced this issue Sep 19, 2022
Signed-off-by: Pierre Fenoll <[email protected]>
@fenollp
Copy link
Collaborator

fenollp commented Sep 19, 2022

#602 isn't getting an error about a property named "type". If you share your code it's obviously easier to reproduce your bug! Please do that.

Note however that having additional fields sibling to $ref isn't a great idea.

                type:
                    $ref: '#/components/schemas/NamespaceType'  # $ref
                    description: Type of this namespace.  # ignored field sibling to $ref

From https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#fixed-fields-19

This object cannot be extended with additional properties and any properties added SHALL be ignored.

FYI the biggest change to validation that is part of this range of releases is validation of schema examples and that's the validation error I am getting:

=== RUN   TestIssue601
    issue601_test.go:15: 
        	Error Trace:	issue601_test.go:15
        	Error:      	Received unexpected error:
        	            	invalid components: invalid schema example: Error at "/fridgecgroup": property "fridgecgroup" is missing
        	            	Schema:
        	            	  {
        	            	    "description": "Information about a specific process, such as its PID, name, and command line\narguments, the references (IDs) of the namespaces the process is joined to.",
        	            	    "example": {
        	            	      "cmdline": [
        	            	        "/sbin/init",
        	            	        "fixrtc",
        	            	        "splash"
        	            	      ],
        	            	      "cpucgroup": "/init.scope",
        	            	      "name": "systemd",
        	            	      "namespaces": {
        	            	        "cgroup": 4026531835,
        	            	        "ipc": 4026531839,
        	            	        "mnt": 4026531840,
        	            	        "net": 4026531905,
        	            	        "pid": 4026531836,
        	            	        "user": 4026531837,
        	            	        "uts": 4026531838
        	            	      },
        	            	      "pid": 1,
        	            	      "ppid": 0,
        	            	      "starttime": 0
        	            	    },
        	            	    "properties": {
        	            	      "cmdline": {
        	            	        "description": "The command line arguments of the process, including the process binary file\nname. Taken from /proc/$PID/cmdline, see also\n[https://man7.org/linux/man-pages/man5/proc.5.html](proc(5)).",
        	            	        "items": {
        	            	          "type": "string"
        	            	        },
        	            	        "type": "array"
        	            	      },
        	            	      "cpucgroup": {
        	            	        "description": "The (CPU) cgroup (control group) path name in the hierarchy this process is in. The\npath name does not specify the root mount path of the complete hierarchy, but\nonly the (pseudo) absolute path starting from the root of the particular (v1) or\nunified (v2) cgroup hierarchy.",
        	            	        "type": "string"
        	            	      },
        	            	      "fridgecgroup": {
        	            	        "description": "The freezer cgroup path name in the hierarchy this process is in.",
        	            	        "type": "string"
        	            	      },
        	            	      "fridgefrozen": {
        	            	        "description": "The effective freezer state of this process.",
        	            	        "type": "boolean"
        	            	      },
        	            	      "name": {
        	            	        "description": "A synthesized name of the process:\n- a name set by the process itself,\n- a name derived from the command line of the process.",
        	            	        "type": "string"
        	            	      },
        	            	      "namespaces": {
        	            	        "$ref": "#/components/schemas/NamespacesSet"
        	            	      },
        	            	      "pid": {
        	            	        "description": "The process identifier (PID) of this process.",
        	            	        "format": "int32",
        	            	        "type": "integer"
        	            	      },
        	            	      "ppid": {
        	            	        "description": "The PID of the parent process, or 0 if there is no parent process. On Linux, the\nonly processes without a parent are the initial process PID 1 and the PID 2\nkthreadd kernel threads \"process\".",
        	            	        "format": "int32",
        	            	        "type": "integer"
        	            	      },
        	            	      "starttime": {
        	            	        "description": "The time this process started after system boot and expressed in clock ticks.\nIt is taken from /proc/$PID/stat, see also\n[https://man7.org/linux/man-pages/man5/proc.5.html](proc(5)).",
        	            	        "format": "int64",
        	            	        "type": "integer"
        	            	      }
        	            	    },
        	            	    "required": [
        	            	      "pid",
        	            	      "ppid",
        	            	      "name",
        	            	      "cmdline",
        	            	      "starttime",
        	            	      "namespaces",
        	            	      "cpucgroup",
        	            	      "fridgecgroup",
        	            	      "fridgefrozen"
        	            	    ],
        	            	    "type": "object"
        	            	  }
        	            	
        	            	Value:
        	            	  {
        	            	    "cmdline": [
        	            	      "/sbin/init",
        	            	      "fixrtc",
        	            	      "splash"
        	            	    ],
        	            	    "cpucgroup": "/init.scope",
        	            	    "name": "systemd",
        	            	    "namespaces": {
        	            	      "cgroup": 4026531835,
        	            	      "ipc": 4026531839,
        	            	      "mnt": 4026531840,
        	            	      "net": 4026531905,
        	            	      "pid": 4026531836,
        	            	      "user": 4026531837,
        	            	      "uts": 4026531838
        	            	    },
        	            	    "pid": 1,
        	            	    "ppid": 0,
        	            	    "starttime": 0
        	            	  }
        	            	 | Error at "/fridgefrozen": property "fridgefrozen" is missing
        	            	Schema:
        	            	  {
        	            	    "description": "Information about a specific process, such as its PID, name, and command line\narguments, the references (IDs) of the namespaces the process is joined to.",
        	            	    "example": {
        	            	      "cmdline": [
        	            	        "/sbin/init",
        	            	        "fixrtc",
        	            	        "splash"
        	            	      ],
        	            	      "cpucgroup": "/init.scope",
        	            	      "name": "systemd",
        	            	      "namespaces": {
        	            	        "cgroup": 4026531835,
        	            	        "ipc": 4026531839,
        	            	        "mnt": 4026531840,
        	            	        "net": 4026531905,
        	            	        "pid": 4026531836,
        	            	        "user": 4026531837,
        	            	        "uts": 4026531838
        	            	      },
        	            	      "pid": 1,
        	            	      "ppid": 0,
        	            	      "starttime": 0
        	            	    },
        	            	    "properties": {
        	            	      "cmdline": {
        	            	        "description": "The command line arguments of the process, including the process binary file\nname. Taken from /proc/$PID/cmdline, see also\n[https://man7.org/linux/man-pages/man5/proc.5.html](proc(5)).",
        	            	        "items": {
        	            	          "type": "string"
        	            	        },
        	            	        "type": "array"
        	            	      },
        	            	      "cpucgroup": {
        	            	        "description": "The (CPU) cgroup (control group) path name in the hierarchy this process is in. The\npath name does not specify the root mount path of the complete hierarchy, but\nonly the (pseudo) absolute path starting from the root of the particular (v1) or\nunified (v2) cgroup hierarchy.",
        	            	        "type": "string"
        	            	      },
        	            	      "fridgecgroup": {
        	            	        "description": "The freezer cgroup path name in the hierarchy this process is in.",
        	            	        "type": "string"
        	            	      },
        	            	      "fridgefrozen": {
        	            	        "description": "The effective freezer state of this process.",
        	            	        "type": "boolean"
        	            	      },
        	            	      "name": {
        	            	        "description": "A synthesized name of the process:\n- a name set by the process itself,\n- a name derived from the command line of the process.",
        	            	        "type": "string"
        	            	      },
        	            	      "namespaces": {
        	            	        "$ref": "#/components/schemas/NamespacesSet"
        	            	      },
        	            	      "pid": {
        	            	        "description": "The process identifier (PID) of this process.",
        	            	        "format": "int32",
        	            	        "type": "integer"
        	            	      },
        	            	      "ppid": {
        	            	        "description": "The PID of the parent process, or 0 if there is no parent process. On Linux, the\nonly processes without a parent are the initial process PID 1 and the PID 2\nkthreadd kernel threads \"process\".",
        	            	        "format": "int32",
        	            	        "type": "integer"
        	            	      },
        	            	      "starttime": {
        	            	        "description": "The time this process started after system boot and expressed in clock ticks.\nIt is taken from /proc/$PID/stat, see also\n[https://man7.org/linux/man-pages/man5/proc.5.html](proc(5)).",
        	            	        "format": "int64",
        	            	        "type": "integer"
        	            	      }
        	            	    },
        	            	    "required": [
        	            	      "pid",
        	            	      "ppid",
        	            	      "name",
        	            	      "cmdline",
        	            	      "starttime",
        	            	      "namespaces",
        	            	      "cpucgroup",
        	            	      "fridgecgroup",
        	            	      "fridgefrozen"
        	            	    ],
        	            	    "type": "object"
        	            	  }
        	            	
        	            	Value:
        	            	  {
        	            	    "cmdline": [
        	            	      "/sbin/init",
        	            	      "fixrtc",
        	            	      "splash"
        	            	    ],
        	            	    "cpucgroup": "/init.scope",
        	            	    "name": "systemd",
        	            	    "namespaces": {
        	            	      "cgroup": 4026531835,
        	            	      "ipc": 4026531839,
        	            	      "mnt": 4026531840,
        	            	      "net": 4026531905,
        	            	      "pid": 4026531836,
        	            	      "user": 4026531837,
        	            	      "uts": 4026531838
        	            	    },
        	            	    "pid": 1,
        	            	    "ppid": 0,
        	            	    "starttime": 0
        	            	  }
        	            	 | 
        	Test:       	TestIssue601

@thediveo
Copy link
Author

Note however that having additional fields sibling to $ref isn't a great idea.

                type:
                    $ref: '#/components/schemas/NamespaceType'  # $ref
                    description: Type of this namespace.  # ignored field sibling to $ref

From https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#fixed-fields-19

This object cannot be extended with additional properties and any properties added SHALL be ignored.

I've used Apicurio for creating the OpenAPI specification and that's what it offers. In its workflow it's normal to describe the field itself, more so as the same type might be used in different fields for differing purposes.

Looks as if the editor and other validators need to pick this up ... or not. I'll rather stick with the old version as looking at my limited work budget I will rather focus on functionality of the things I build rather than dealing with spec validation in areas where it doesn't produce any indirect value to my employer and our customers, but instead costs.

Closing this to reduce the issue load.

fenollp added a commit to fenollp/kin-openapi that referenced this issue Sep 19, 2022
Signed-off-by: Pierre Fenoll <[email protected]>
fenollp added a commit to fenollp/kin-openapi that referenced this issue Sep 19, 2022
Signed-off-by: Pierre Fenoll <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants