Browse Source

Merge pull request #28038 from bfirsh/add-validate-swagger

Validation for swagger.yaml
Vincent Demeester 8 years ago
parent
commit
9075aa4ddd
5 changed files with 81 additions and 63 deletions
  1. 9 0
      Dockerfile
  2. 54 63
      api/swagger.yaml
  3. 4 0
      hack/validate/.swagger-yamllint
  4. 1 0
      hack/validate/default
  5. 13 0
      hack/validate/swagger

+ 9 - 0
Dockerfile

@@ -195,6 +195,15 @@ RUN git clone https://github.com/docker/docker-py.git /docker-py \
 	&& git checkout -q $DOCKER_PY_COMMIT \
 	&& git checkout -q $DOCKER_PY_COMMIT \
 	&& pip install -r test-requirements.txt
 	&& pip install -r test-requirements.txt
 
 
+# Install yamllint for validating swagger.yaml
+RUN pip install yamllint==1.5.0
+
+# Install go-swagger for validating swagger.yaml
+ENV GO_SWAGGER_COMMIT c28258affb0b6251755d92489ef685af8d4ff3eb
+RUN git clone https://github.com/go-swagger/go-swagger.git /go/src/github.com/go-swagger/go-swagger \
+	&& (cd /go/src/github.com/go-swagger/go-swagger && git checkout -q $GO_SWAGGER_COMMIT) \
+	&& go install -v github.com/go-swagger/go-swagger/cmd/swagger
+
 # Set user.email so crosbymichael's in-container merge commits go smoothly
 # Set user.email so crosbymichael's in-container merge commits go smoothly
 RUN git config --global user.email 'docker-dummy@example.com'
 RUN git config --global user.email 'docker-dummy@example.com'
 
 

+ 54 - 63
api/swagger.yaml

@@ -12,6 +12,8 @@ basePath: "/v1.25"
 info:
 info:
   title: "Docker Remote API"
   title: "Docker Remote API"
   version: "1.25"
   version: "1.25"
+  x-logo:
+    url: "https://docs.docker.com/images/logo-docker-main.png"
   description: |
   description: |
     The Docker API is an HTTP REST API served by Docker Engine. It is the API the Docker client uses to communicate with the Engine, so everything the Docker client can do can be done with the API.
     The Docker API is an HTTP REST API served by Docker Engine. It is the API the Docker client uses to communicate with the Engine, so everything the Docker client can do can be done with the API.
 
 
@@ -234,7 +236,7 @@ definitions:
       BlkioWeight:
       BlkioWeight:
         description: "Block IO weight (relative weight)."
         description: "Block IO weight (relative weight)."
         type: "integer"
         type: "integer"
-        minimum: 10
+        minimum: 0
         maximum: 1000
         maximum: 1000
       BlkioWeightDevice:
       BlkioWeightDevice:
         description: |
         description: |
@@ -1692,6 +1694,7 @@ definitions:
         $ref: "#/definitions/SwarmSpec"
         $ref: "#/definitions/SwarmSpec"
   TaskSpec:
   TaskSpec:
     description: "User modifiable task configuration."
     description: "User modifiable task configuration."
+    type: "object"
     properties:
     properties:
       ContainerSpec:
       ContainerSpec:
         type: "object"
         type: "object"
@@ -2277,9 +2280,6 @@ paths:
                 NetworkSettings:
                 NetworkSettings:
                   Networks:
                   Networks:
                     bridge:
                     bridge:
-                      IPAMConfig: null
-                      Links: null
-                      Aliases: null
                       NetworkID: "7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812"
                       NetworkID: "7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812"
                       EndpointID: "2cdc4edb1ded3631c81f57966563e5c8525b81121bb3706a9a9a3ae102711f3f"
                       EndpointID: "2cdc4edb1ded3631c81f57966563e5c8525b81121bb3706a9a9a3ae102711f3f"
                       Gateway: "172.17.0.1"
                       Gateway: "172.17.0.1"
@@ -2315,9 +2315,6 @@ paths:
                 NetworkSettings:
                 NetworkSettings:
                   Networks:
                   Networks:
                     bridge:
                     bridge:
-                      IPAMConfig: null
-                      Links: null
-                      Aliases: null
                       NetworkID: "7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812"
                       NetworkID: "7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812"
                       EndpointID: "88eaed7b37b38c2a3f0c4bc796494fdf51b270c2d22656412a2ca5d559a64d7a"
                       EndpointID: "88eaed7b37b38c2a3f0c4bc796494fdf51b270c2d22656412a2ca5d559a64d7a"
                       Gateway: "172.17.0.1"
                       Gateway: "172.17.0.1"
@@ -2346,9 +2343,6 @@ paths:
                 NetworkSettings:
                 NetworkSettings:
                   Networks:
                   Networks:
                     bridge:
                     bridge:
-                      IPAMConfig: null
-                      Links: null
-                      Aliases: null
                       NetworkID: "7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812"
                       NetworkID: "7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812"
                       EndpointID: "8b27c041c30326d59cd6e6f510d4f8d1d570a228466f956edf7815508f78e30d"
                       EndpointID: "8b27c041c30326d59cd6e6f510d4f8d1d570a228466f956edf7815508f78e30d"
                       Gateway: "172.17.0.1"
                       Gateway: "172.17.0.1"
@@ -2377,9 +2371,6 @@ paths:
                 NetworkSettings:
                 NetworkSettings:
                   Networks:
                   Networks:
                     bridge:
                     bridge:
-                      IPAMConfig: null
-                      Links: null
-                      Aliases: null
                       NetworkID: "7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812"
                       NetworkID: "7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812"
                       EndpointID: "d91c7b2f0644403d7ef3095985ea0e2370325cd2332ff3a3225c4247328e66e9"
                       EndpointID: "d91c7b2f0644403d7ef3095985ea0e2370325cd2332ff3a3225c4247328e66e9"
                       Gateway: "172.17.0.1"
                       Gateway: "172.17.0.1"
@@ -2721,10 +2712,8 @@ paths:
                   - "-c"
                   - "-c"
                   - "exit 9"
                   - "exit 9"
                 Domainname: ""
                 Domainname: ""
-                Entrypoint: null
                 Env:
                 Env:
                   - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
                   - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
-                ExposedPorts: null
                 Hostname: "ba033ac44011"
                 Hostname: "ba033ac44011"
                 Image: "ubuntu"
                 Image: "ubuntu"
                 Labels:
                 Labels:
@@ -2733,7 +2722,6 @@ paths:
                   com.example.version: "1.0"
                   com.example.version: "1.0"
                 MacAddress: ""
                 MacAddress: ""
                 NetworkDisabled: false
                 NetworkDisabled: false
-                OnBuild: null
                 OpenStdin: false
                 OpenStdin: false
                 StdinOnce: false
                 StdinOnce: false
                 Tty: false
                 Tty: false
@@ -2744,9 +2732,7 @@ paths:
                 StopSignal: "SIGTERM"
                 StopSignal: "SIGTERM"
               Created: "2015-01-06T15:47:31.485331387Z"
               Created: "2015-01-06T15:47:31.485331387Z"
               Driver: "devicemapper"
               Driver: "devicemapper"
-              ExecIDs: null
               HostConfig:
               HostConfig:
-                Binds: null
                 MaximumIOps: 0
                 MaximumIOps: 0
                 MaximumIOBps: 0
                 MaximumIOBps: 0
                 BlkioWeight: 0
                 BlkioWeight: 0
@@ -2760,8 +2746,6 @@ paths:
                   - {}
                   - {}
                 BlkioDeviceWriteIOps:
                 BlkioDeviceWriteIOps:
                   - {}
                   - {}
-                CapAdd: null
-                CapDrop: null
                 ContainerIDFile: ""
                 ContainerIDFile: ""
                 CpusetCpus: ""
                 CpusetCpus: ""
                 CpusetMems: ""
                 CpusetMems: ""
@@ -2769,12 +2753,7 @@ paths:
                 CpuShares: 0
                 CpuShares: 0
                 CpuPeriod: 100000
                 CpuPeriod: 100000
                 Devices: []
                 Devices: []
-                Dns: null
-                DnsOptions: null
-                DnsSearch: null
-                ExtraHosts: null
                 IpcMode: ""
                 IpcMode: ""
-                Links: null
                 LxcConf: []
                 LxcConf: []
                 Memory: 0
                 Memory: 0
                 MemorySwap: 0
                 MemorySwap: 0
@@ -2792,13 +2771,9 @@ paths:
                   MaximumRetryCount: 2
                   MaximumRetryCount: 2
                   Name: "on-failure"
                   Name: "on-failure"
                 LogConfig:
                 LogConfig:
-                  Config: null
                   Type: "json-file"
                   Type: "json-file"
-                SecurityOpt: null
                 Sysctls:
                 Sysctls:
                   net.ipv4.ip_forward: "1"
                   net.ipv4.ip_forward: "1"
-                StorageOpt: null
-                VolumesFrom: null
                 Ulimits:
                 Ulimits:
                   - {}
                   - {}
                 VolumeDriver: ""
                 VolumeDriver: ""
@@ -2816,7 +2791,6 @@ paths:
                 HairpinMode: false
                 HairpinMode: false
                 LinkLocalIPv6Address: ""
                 LinkLocalIPv6Address: ""
                 LinkLocalIPv6PrefixLen: 0
                 LinkLocalIPv6PrefixLen: 0
-                Ports: null
                 SandboxKey: ""
                 SandboxKey: ""
                 SecondaryIPAddresses: null
                 SecondaryIPAddresses: null
                 SecondaryIPv6Addresses: null
                 SecondaryIPv6Addresses: null
@@ -3865,18 +3839,25 @@ paths:
               type: "string"
               type: "string"
               description: "TODO"
               description: "TODO"
         400:
         400:
-          description: "client error, bad parameter, details in JSON response body, one of: must specify path parameter (path cannot be empty) not a directory (path was asserted to be a directory but exists as a file)"
+          description: "Bad parameter"
           schema:
           schema:
-            $ref: "#/definitions/ErrorResponse"
+            allOf:
+              - $ref: "#/definitions/ErrorResponse"
+              - type: "object"
+                properties:
+                  message:
+                    description: "The error message. Either \"must specify path parameter\" (path cannot be empty) or \"not a directory\" (path was asserted to be a directory but exists as a file)."
+                    type: "string"
+                    x-nullable: false
         404:
         404:
-          description: "client error, resource not found, one of: 1) no such container (container id does not exist) 2) no such file or directory (path resource does not exist)"
+          description: "Container or path does not exist"
           schema:
           schema:
             $ref: "#/definitions/ErrorResponse"
             $ref: "#/definitions/ErrorResponse"
           examples:
           examples:
             application/json:
             application/json:
               message: "No such container: c2ada9df5af8"
               message: "No such container: c2ada9df5af8"
         500:
         500:
-          description: "server error"
+          description: "Server error"
           schema:
           schema:
             $ref: "#/definitions/ErrorResponse"
             $ref: "#/definitions/ErrorResponse"
       parameters:
       parameters:
@@ -3902,11 +3883,18 @@ paths:
         200:
         200:
           description: "no error"
           description: "no error"
         400:
         400:
-          description: "client error, bad parameter, details in JSON response body, one of: must specify path parameter (path cannot be empty) not a directory (path was asserted to be a directory but exists as a file)"
+          description: "Bad parameter"
           schema:
           schema:
-            $ref: "#/definitions/ErrorResponse"
+            allOf:
+              - $ref: "#/definitions/ErrorResponse"
+              - type: "object"
+                properties:
+                  message:
+                    description: "The error message. Either \"must specify path parameter\" (path cannot be empty) or \"not a directory\" (path was asserted to be a directory but exists as a file)."
+                    type: "string"
+                    x-nullable: false
         404:
         404:
-          description: "client error, resource not found, one of: 1) no such container (container id does not exist) 2) no such file or directory (path resource does not exist)"
+          description: "Container or path does not exist"
           schema:
           schema:
             $ref: "#/definitions/ErrorResponse"
             $ref: "#/definitions/ErrorResponse"
           examples:
           examples:
@@ -3997,25 +3985,33 @@ paths:
               $ref: "#/definitions/ImageSummary"
               $ref: "#/definitions/ImageSummary"
           examples:
           examples:
             application/json:
             application/json:
-              - RepoTags:
+              - Id: "sha256:e216a057b1cb1efc11f8a268f37ef62083e70b1b38323ba252e25ac88904a7e8"
+                ParentId: ""
+                RepoTags:
                   - "ubuntu:12.04"
                   - "ubuntu:12.04"
                   - "ubuntu:precise"
                   - "ubuntu:precise"
-                  - "ubuntu:latest"
-                Id: "8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c"
-                Created: 1365714795
-                Size: 131506275
-                VirtualSize: 131506275
+                RepoDigests:
+                  - "ubuntu@sha256:992069aee4016783df6345315302fa59681aae51a8eeb2f889dea59290f21787"
+                Created: 1474925151
+                Size: 103579269
+                VirtualSize: 103579269
+                SharedSize: 0
                 Labels: {}
                 Labels: {}
-              - RepoTags:
+                Containers: 2
+              - Id: "sha256:3e314f95dcace0f5e4fd37b10862fe8398e3c60ed36600bc0ca5fda78b087175"
+                ParentId: ""
+                RepoTags:
                   - "ubuntu:12.10"
                   - "ubuntu:12.10"
                   - "ubuntu:quantal"
                   - "ubuntu:quantal"
-                ParentId: "27cf784147099545"
-                Id: "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc"
-                Created: 1364102658
-                Size: 24653
-                VirtualSize: 180116135
-                Labels:
-                  com.example.version: "v1"
+                RepoDigests:
+                  - "ubuntu@sha256:002fba3e3255af10be97ea26e476692a7ebed0bb074a9ab960b2e7a1526b15d7"
+                  - "ubuntu@sha256:68ea0200f0b90df725d99d823905b04cf844f6039ef60c60bf3e019915017bd3"
+                Created: 1403128455
+                Size: 172064416
+                VirtualSize: 172064416
+                SharedSize: 0
+                Labels: {}
+                Containers: 5
         500:
         500:
           description: "server error"
           description: "server error"
           schema:
           schema:
@@ -4241,7 +4237,6 @@ paths:
               ContainerConfig:
               ContainerConfig:
                 Tty: false
                 Tty: false
                 Hostname: "e611e15f9c9d"
                 Hostname: "e611e15f9c9d"
-                Volumes: null
                 Domainname: ""
                 Domainname: ""
                 AttachStdout: false
                 AttachStdout: false
                 PublishService: ""
                 PublishService: ""
@@ -4253,7 +4248,6 @@ paths:
                 Image: "91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c"
                 Image: "91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c"
                 User: ""
                 User: ""
                 WorkingDir: ""
                 WorkingDir: ""
-                Entrypoint: null
                 MacAddress: ""
                 MacAddress: ""
                 AttachStderr: false
                 AttachStderr: false
                 Labels:
                 Labels:
@@ -4262,7 +4256,6 @@ paths:
                   com.example.vendor: "Acme"
                   com.example.vendor: "Acme"
                 Env:
                 Env:
                   - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
                   - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
-                ExposedPorts: null
                 Cmd:
                 Cmd:
                   - "/bin/sh"
                   - "/bin/sh"
                   - "-c"
                   - "-c"
@@ -4274,7 +4267,6 @@ paths:
               Created: "2015-09-10T08:30:53.26995814Z"
               Created: "2015-09-10T08:30:53.26995814Z"
               GraphDriver:
               GraphDriver:
                 Name: "aufs"
                 Name: "aufs"
-                Data: null
               RepoDigests:
               RepoDigests:
                 - "localhost:5000/test/busybox/example@sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf"
                 - "localhost:5000/test/busybox/example@sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf"
               RepoTags:
               RepoTags:
@@ -4293,17 +4285,14 @@ paths:
                 AttachStdout: false
                 AttachStdout: false
                 Tty: false
                 Tty: false
                 Hostname: "e611e15f9c9d"
                 Hostname: "e611e15f9c9d"
-                Volumes: null
                 Cmd:
                 Cmd:
                   - "/bin/bash"
                   - "/bin/bash"
-                ExposedPorts: null
                 Env:
                 Env:
                   - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
                   - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
                 Labels:
                 Labels:
                   com.example.vendor: "Acme"
                   com.example.vendor: "Acme"
                   com.example.version: "1.0"
                   com.example.version: "1.0"
                   com.example.license: "GPL"
                   com.example.license: "GPL"
-                Entrypoint: null
                 MacAddress: ""
                 MacAddress: ""
                 AttachStderr: false
                 AttachStderr: false
                 WorkingDir: ""
                 WorkingDir: ""
@@ -4376,7 +4365,7 @@ paths:
               - Id: "6cfa4d1f33fb861d4d114f43b25abd0ac737509268065cdfd69d544a59c85ab8"
               - Id: "6cfa4d1f33fb861d4d114f43b25abd0ac737509268065cdfd69d544a59c85ab8"
                 Created: 1398108222
                 Created: 1398108222
                 CreatedBy: "/bin/sh -c #(nop) MAINTAINER Tianon Gravi <admwiggin@gmail.com> - mkimage-debootstrap.sh -i iproute,iputils-ping,ubuntu-minimal -t lucid.tar.xz lucid http://archive.ubuntu.com/ubuntu/"
                 CreatedBy: "/bin/sh -c #(nop) MAINTAINER Tianon Gravi <admwiggin@gmail.com> - mkimage-debootstrap.sh -i iproute,iputils-ping,ubuntu-minimal -t lucid.tar.xz lucid http://archive.ubuntu.com/ubuntu/"
-                Tags: null
+                Tags: []
                 Size: 0
                 Size: 0
                 Comment: ""
                 Comment: ""
               - Id: "511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158"
               - Id: "511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158"
@@ -4834,7 +4823,6 @@ paths:
               RegistryConfig:
               RegistryConfig:
                 IndexConfigs:
                 IndexConfigs:
                   docker.io:
                   docker.io:
-                    Mirrors: null
                     Name: "docker.io"
                     Name: "docker.io"
                     Official: true
                     Official: true
                     Secure: true
                     Secure: true
@@ -5035,6 +5023,7 @@ paths:
               timeNano:
               timeNano:
                 description: "Timestamp of event, with nanosecond accuracy"
                 description: "Timestamp of event, with nanosecond accuracy"
                 type: "integer"
                 type: "integer"
+                format: "int64"
           examples:
           examples:
             application/json:
             application/json:
               Type: "container"
               Type: "container"
@@ -5046,7 +5035,6 @@ paths:
                   image: "alpine"
                   image: "alpine"
                   name: "my-container"
                   name: "my-container"
               time: 1461943101
               time: 1461943101
-              timeNano: 1461943101381709551
         500:
         500:
           description: "server error"
           description: "server error"
           schema:
           schema:
@@ -5425,6 +5413,7 @@ paths:
                     com.example.some-label: "some-value"
                     com.example.some-label: "some-value"
                     com.example.some-other-label: "some-other-value"
                     com.example.some-other-label: "some-other-value"
                   Scope: "local"
                   Scope: "local"
+                  Options: {}
               Warnings: []
               Warnings: []
         500:
         500:
           description: "Server error"
           description: "Server error"
@@ -6496,7 +6485,8 @@ paths:
           schema:
           schema:
             allOf:
             allOf:
               - $ref: "#/definitions/ServiceSpec"
               - $ref: "#/definitions/ServiceSpec"
-              - example:
+              - type: "object"
+                example:
                   Name: "web"
                   Name: "web"
                   TaskTemplate:
                   TaskTemplate:
                     ContainerSpec:
                     ContainerSpec:
@@ -6621,7 +6611,8 @@ paths:
           schema:
           schema:
             allOf:
             allOf:
               - $ref: "#/definitions/ServiceSpec"
               - $ref: "#/definitions/ServiceSpec"
-              - example:
+              - type: "object"
+                example:
                   Name: "top"
                   Name: "top"
                   TaskTemplate:
                   TaskTemplate:
                     ContainerSpec:
                     ContainerSpec:

+ 4 - 0
hack/validate/.swagger-yamllint

@@ -0,0 +1,4 @@
+extends: default
+rules:
+  document-start: disable
+  line-length: disable

+ 1 - 0
hack/validate/default

@@ -9,6 +9,7 @@ export SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
 . $SCRIPTDIR/gofmt
 . $SCRIPTDIR/gofmt
 . $SCRIPTDIR/lint
 . $SCRIPTDIR/lint
 . $SCRIPTDIR/pkg-imports
 . $SCRIPTDIR/pkg-imports
+. $SCRIPTDIR/swagger
 . $SCRIPTDIR/test-imports
 . $SCRIPTDIR/test-imports
 . $SCRIPTDIR/toml
 . $SCRIPTDIR/toml
 . $SCRIPTDIR/vet
 . $SCRIPTDIR/vet

+ 13 - 0
hack/validate/swagger

@@ -0,0 +1,13 @@
+#!/bin/bash
+set -e
+export SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+source "${SCRIPTDIR}/.validate"
+
+IFS=$'\n'
+files=( $(validate_diff --diff-filter=ACMR --name-only -- 'api/swagger.yaml' || true) )
+unset IFS
+
+if [ ${#files[@]} -gt 0 ]; then
+  yamllint -c ${SCRIPTDIR}/.swagger-yamllint api/swagger.yaml
+  swagger validate api/swagger.yaml
+fi