From b0099004e249ac7f9df92213c0186f95fa4cbb0f Mon Sep 17 00:00:00 2001
From: Aaron Lehmann <aaron.lehmann@docker.com>
Date: Tue, 12 Jul 2016 12:18:54 -0600
Subject: [PATCH] Document TOOMANYREQUESTS error code

Add entries with this error code in registry/api/v2/descriptors.go.

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
---
 docs/spec/api.md               | 636 +++++++++++++++++++++++++++++++++
 docs/spec/api.md.tmpl          |   7 +
 registry/api/v2/descriptors.go |  49 ++-
 3 files changed, 681 insertions(+), 11 deletions(-)

diff --git a/docs/spec/api.md b/docs/spec/api.md
index 39041146..c4517c0b 100644
--- a/docs/spec/api.md
+++ b/docs/spec/api.md
@@ -126,6 +126,13 @@ reference and shouldn't be used outside the specification other than to
 identify a set of modifications.
 
 <dl>
+  <dt>l</dt>
+  <dd>
+    <ul>
+      <li>Document TOOMANYREQUESTS error code.</li>
+    </ul>
+  </dd>
+
   <dt>k</dt>
   <dd>
     <ul>
@@ -1236,6 +1243,43 @@ The error codes that may be included in the response body are enumerated below:
 
 
 
+###### On Failure: Too Many Requests
+
+```
+429 Too Many Requests
+Content-Length: <length>
+Content-Type: application/json; charset=utf-8
+
+{
+	"errors:" [
+	    {
+            "code": <error code>,
+            "message": "<error message>",
+            "detail": ...
+        },
+        ...
+    ]
+}
+```
+
+The client made too many requests within a time interval.
+
+The following headers will be returned on the response:
+
+|Name|Description|
+|----|-----------|
+|`Content-Length`|Length of the JSON response body.|
+
+
+
+The error codes that may be included in the response body are enumerated below:
+
+|Code|Message|Description|
+|----|-------|-----------|
+| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times |
+
+
+
 
 
 ### Tags
@@ -1411,6 +1455,43 @@ The error codes that may be included in the response body are enumerated below:
 
 
 
+###### On Failure: Too Many Requests
+
+```
+429 Too Many Requests
+Content-Length: <length>
+Content-Type: application/json; charset=utf-8
+
+{
+	"errors:" [
+	    {
+            "code": <error code>,
+            "message": "<error message>",
+            "detail": ...
+        },
+        ...
+    ]
+}
+```
+
+The client made too many requests within a time interval.
+
+The following headers will be returned on the response:
+
+|Name|Description|
+|----|-----------|
+|`Content-Length`|Length of the JSON response body.|
+
+
+
+The error codes that may be included in the response body are enumerated below:
+
+|Code|Message|Description|
+|----|-------|-----------|
+| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times |
+
+
+
 ##### Tags Paginated
 
 ```
@@ -1573,6 +1654,43 @@ The error codes that may be included in the response body are enumerated below:
 
 
 
+###### On Failure: Too Many Requests
+
+```
+429 Too Many Requests
+Content-Length: <length>
+Content-Type: application/json; charset=utf-8
+
+{
+	"errors:" [
+	    {
+            "code": <error code>,
+            "message": "<error message>",
+            "detail": ...
+        },
+        ...
+    ]
+}
+```
+
+The client made too many requests within a time interval.
+
+The following headers will be returned on the response:
+
+|Name|Description|
+|----|-----------|
+|`Content-Length`|Length of the JSON response body.|
+
+
+
+The error codes that may be included in the response body are enumerated below:
+
+|Code|Message|Description|
+|----|-------|-----------|
+| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times |
+
+
+
 
 
 ### Manifest
@@ -1785,6 +1903,43 @@ The error codes that may be included in the response body are enumerated below:
 
 
 
+###### On Failure: Too Many Requests
+
+```
+429 Too Many Requests
+Content-Length: <length>
+Content-Type: application/json; charset=utf-8
+
+{
+	"errors:" [
+	    {
+            "code": <error code>,
+            "message": "<error message>",
+            "detail": ...
+        },
+        ...
+    ]
+}
+```
+
+The client made too many requests within a time interval.
+
+The following headers will be returned on the response:
+
+|Name|Description|
+|----|-----------|
+|`Content-Length`|Length of the JSON response body.|
+
+
+
+The error codes that may be included in the response body are enumerated below:
+
+|Code|Message|Description|
+|----|-------|-----------|
+| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times |
+
+
+
 
 #### PUT Manifest
 
@@ -1997,6 +2152,43 @@ The error codes that may be included in the response body are enumerated below:
 
 
 
+###### On Failure: Too Many Requests
+
+```
+429 Too Many Requests
+Content-Length: <length>
+Content-Type: application/json; charset=utf-8
+
+{
+	"errors:" [
+	    {
+            "code": <error code>,
+            "message": "<error message>",
+            "detail": ...
+        },
+        ...
+    ]
+}
+```
+
+The client made too many requests within a time interval.
+
+The following headers will be returned on the response:
+
+|Name|Description|
+|----|-----------|
+|`Content-Length`|Length of the JSON response body.|
+
+
+
+The error codes that may be included in the response body are enumerated below:
+
+|Code|Message|Description|
+|----|-------|-----------|
+| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times |
+
+
+
 ###### On Failure: Missing Layer(s)
 
 ```
@@ -2229,6 +2421,43 @@ The error codes that may be included in the response body are enumerated below:
 
 
 
+###### On Failure: Too Many Requests
+
+```
+429 Too Many Requests
+Content-Length: <length>
+Content-Type: application/json; charset=utf-8
+
+{
+	"errors:" [
+	    {
+            "code": <error code>,
+            "message": "<error message>",
+            "detail": ...
+        },
+        ...
+    ]
+}
+```
+
+The client made too many requests within a time interval.
+
+The following headers will be returned on the response:
+
+|Name|Description|
+|----|-----------|
+|`Content-Length`|Length of the JSON response body.|
+
+
+
+The error codes that may be included in the response body are enumerated below:
+
+|Code|Message|Description|
+|----|-------|-----------|
+| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times |
+
+
+
 ###### On Failure: Unknown Manifest
 
 ```
@@ -2529,6 +2758,43 @@ The error codes that may be included in the response body are enumerated below:
 
 
 
+###### On Failure: Too Many Requests
+
+```
+429 Too Many Requests
+Content-Length: <length>
+Content-Type: application/json; charset=utf-8
+
+{
+	"errors:" [
+	    {
+            "code": <error code>,
+            "message": "<error message>",
+            "detail": ...
+        },
+        ...
+    ]
+}
+```
+
+The client made too many requests within a time interval.
+
+The following headers will be returned on the response:
+
+|Name|Description|
+|----|-----------|
+|`Content-Length`|Length of the JSON response body.|
+
+
+
+The error codes that may be included in the response body are enumerated below:
+
+|Code|Message|Description|
+|----|-------|-----------|
+| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times |
+
+
+
 ##### Fetch Blob Part
 
 ```
@@ -2762,6 +3028,43 @@ The error codes that may be included in the response body are enumerated below:
 
 
 
+###### On Failure: Too Many Requests
+
+```
+429 Too Many Requests
+Content-Length: <length>
+Content-Type: application/json; charset=utf-8
+
+{
+	"errors:" [
+	    {
+            "code": <error code>,
+            "message": "<error message>",
+            "detail": ...
+        },
+        ...
+    ]
+}
+```
+
+The client made too many requests within a time interval.
+
+The following headers will be returned on the response:
+
+|Name|Description|
+|----|-----------|
+|`Content-Length`|Length of the JSON response body.|
+
+
+
+The error codes that may be included in the response body are enumerated below:
+
+|Code|Message|Description|
+|----|-------|-----------|
+| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times |
+
+
+
 
 #### DELETE Blob
 
@@ -3003,6 +3306,43 @@ The error codes that may be included in the response body are enumerated below:
 
 
 
+###### On Failure: Too Many Requests
+
+```
+429 Too Many Requests
+Content-Length: <length>
+Content-Type: application/json; charset=utf-8
+
+{
+	"errors:" [
+	    {
+            "code": <error code>,
+            "message": "<error message>",
+            "detail": ...
+        },
+        ...
+    ]
+}
+```
+
+The client made too many requests within a time interval.
+
+The following headers will be returned on the response:
+
+|Name|Description|
+|----|-----------|
+|`Content-Length`|Length of the JSON response body.|
+
+
+
+The error codes that may be included in the response body are enumerated below:
+
+|Code|Message|Description|
+|----|-------|-----------|
+| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times |
+
+
+
 
 
 ### Initiate Blob Upload
@@ -3216,6 +3556,43 @@ The error codes that may be included in the response body are enumerated below:
 
 
 
+###### On Failure: Too Many Requests
+
+```
+429 Too Many Requests
+Content-Length: <length>
+Content-Type: application/json; charset=utf-8
+
+{
+	"errors:" [
+	    {
+            "code": <error code>,
+            "message": "<error message>",
+            "detail": ...
+        },
+        ...
+    ]
+}
+```
+
+The client made too many requests within a time interval.
+
+The following headers will be returned on the response:
+
+|Name|Description|
+|----|-----------|
+|`Content-Length`|Length of the JSON response body.|
+
+
+
+The error codes that may be included in the response body are enumerated below:
+
+|Code|Message|Description|
+|----|-------|-----------|
+| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times |
+
+
+
 ##### Initiate Resumable Blob Upload
 
 ```
@@ -3396,6 +3773,43 @@ The error codes that may be included in the response body are enumerated below:
 
 
 
+###### On Failure: Too Many Requests
+
+```
+429 Too Many Requests
+Content-Length: <length>
+Content-Type: application/json; charset=utf-8
+
+{
+	"errors:" [
+	    {
+            "code": <error code>,
+            "message": "<error message>",
+            "detail": ...
+        },
+        ...
+    ]
+}
+```
+
+The client made too many requests within a time interval.
+
+The following headers will be returned on the response:
+
+|Name|Description|
+|----|-----------|
+|`Content-Length`|Length of the JSON response body.|
+
+
+
+The error codes that may be included in the response body are enumerated below:
+
+|Code|Message|Description|
+|----|-------|-----------|
+| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times |
+
+
+
 ##### Mount Blob
 
 ```
@@ -3594,6 +4008,43 @@ The error codes that may be included in the response body are enumerated below:
 
 
 
+###### On Failure: Too Many Requests
+
+```
+429 Too Many Requests
+Content-Length: <length>
+Content-Type: application/json; charset=utf-8
+
+{
+	"errors:" [
+	    {
+            "code": <error code>,
+            "message": "<error message>",
+            "detail": ...
+        },
+        ...
+    ]
+}
+```
+
+The client made too many requests within a time interval.
+
+The following headers will be returned on the response:
+
+|Name|Description|
+|----|-----------|
+|`Content-Length`|Length of the JSON response body.|
+
+
+
+The error codes that may be included in the response body are enumerated below:
+
+|Code|Message|Description|
+|----|-------|-----------|
+| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times |
+
+
+
 
 
 ### Blob Upload
@@ -3826,6 +4277,43 @@ The error codes that may be included in the response body are enumerated below:
 
 
 
+###### On Failure: Too Many Requests
+
+```
+429 Too Many Requests
+Content-Length: <length>
+Content-Type: application/json; charset=utf-8
+
+{
+	"errors:" [
+	    {
+            "code": <error code>,
+            "message": "<error message>",
+            "detail": ...
+        },
+        ...
+    ]
+}
+```
+
+The client made too many requests within a time interval.
+
+The following headers will be returned on the response:
+
+|Name|Description|
+|----|-----------|
+|`Content-Length`|Length of the JSON response body.|
+
+
+
+The error codes that may be included in the response body are enumerated below:
+
+|Code|Message|Description|
+|----|-------|-----------|
+| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times |
+
+
+
 
 #### PATCH Blob Upload
 
@@ -4057,6 +4545,43 @@ The error codes that may be included in the response body are enumerated below:
 
 
 
+###### On Failure: Too Many Requests
+
+```
+429 Too Many Requests
+Content-Length: <length>
+Content-Type: application/json; charset=utf-8
+
+{
+	"errors:" [
+	    {
+            "code": <error code>,
+            "message": "<error message>",
+            "detail": ...
+        },
+        ...
+    ]
+}
+```
+
+The client made too many requests within a time interval.
+
+The following headers will be returned on the response:
+
+|Name|Description|
+|----|-----------|
+|`Content-Length`|Length of the JSON response body.|
+
+
+
+The error codes that may be included in the response body are enumerated below:
+
+|Code|Message|Description|
+|----|-------|-----------|
+| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times |
+
+
+
 ##### Chunked upload
 
 ```
@@ -4296,6 +4821,43 @@ The error codes that may be included in the response body are enumerated below:
 
 
 
+###### On Failure: Too Many Requests
+
+```
+429 Too Many Requests
+Content-Length: <length>
+Content-Type: application/json; charset=utf-8
+
+{
+	"errors:" [
+	    {
+            "code": <error code>,
+            "message": "<error message>",
+            "detail": ...
+        },
+        ...
+    ]
+}
+```
+
+The client made too many requests within a time interval.
+
+The following headers will be returned on the response:
+
+|Name|Description|
+|----|-----------|
+|`Content-Length`|Length of the JSON response body.|
+
+
+
+The error codes that may be included in the response body are enumerated below:
+
+|Code|Message|Description|
+|----|-------|-----------|
+| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times |
+
+
+
 
 #### PUT Blob Upload
 
@@ -4530,6 +5092,43 @@ The error codes that may be included in the response body are enumerated below:
 
 
 
+###### On Failure: Too Many Requests
+
+```
+429 Too Many Requests
+Content-Length: <length>
+Content-Type: application/json; charset=utf-8
+
+{
+	"errors:" [
+	    {
+            "code": <error code>,
+            "message": "<error message>",
+            "detail": ...
+        },
+        ...
+    ]
+}
+```
+
+The client made too many requests within a time interval.
+
+The following headers will be returned on the response:
+
+|Name|Description|
+|----|-----------|
+|`Content-Length`|Length of the JSON response body.|
+
+
+
+The error codes that may be included in the response body are enumerated below:
+
+|Code|Message|Description|
+|----|-------|-----------|
+| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times |
+
+
+
 
 #### DELETE Blob Upload
 
@@ -4752,6 +5351,43 @@ The error codes that may be included in the response body are enumerated below:
 
 
 
+###### On Failure: Too Many Requests
+
+```
+429 Too Many Requests
+Content-Length: <length>
+Content-Type: application/json; charset=utf-8
+
+{
+	"errors:" [
+	    {
+            "code": <error code>,
+            "message": "<error message>",
+            "detail": ...
+        },
+        ...
+    ]
+}
+```
+
+The client made too many requests within a time interval.
+
+The following headers will be returned on the response:
+
+|Name|Description|
+|----|-----------|
+|`Content-Length`|Length of the JSON response body.|
+
+
+
+The error codes that may be included in the response body are enumerated below:
+
+|Code|Message|Description|
+|----|-------|-----------|
+| `TOOMANYREQUESTS` | too many requests | Returned when a client attempts to contact a service too many times |
+
+
+
 
 
 ### Catalog
diff --git a/docs/spec/api.md.tmpl b/docs/spec/api.md.tmpl
index 13a1fc2e..eeafec1e 100644
--- a/docs/spec/api.md.tmpl
+++ b/docs/spec/api.md.tmpl
@@ -126,6 +126,13 @@ reference and shouldn't be used outside the specification other than to
 identify a set of modifications.
 
 <dl>
+  <dt>l</dt>
+  <dd>
+    <ul>
+      <li>Document TOOMANYREQUESTS error code.</li>
+    </ul>
+  </dd>
+
   <dt>k</dt>
   <dd>
     <ul>
diff --git a/registry/api/v2/descriptors.go b/registry/api/v2/descriptors.go
index fc42c1c4..9979abae 100644
--- a/registry/api/v2/descriptors.go
+++ b/registry/api/v2/descriptors.go
@@ -175,6 +175,27 @@ var (
 			errcode.ErrorCodeDenied,
 		},
 	}
+
+	tooManyRequestsDescriptor = ResponseDescriptor{
+		Name:        "Too Many Requests",
+		StatusCode:  http.StatusTooManyRequests,
+		Description: "The client made too many requests within a time interval.",
+		Headers: []ParameterDescriptor{
+			{
+				Name:        "Content-Length",
+				Type:        "integer",
+				Description: "Length of the JSON response body.",
+				Format:      "<length>",
+			},
+		},
+		Body: BodyDescriptor{
+			ContentType: "application/json; charset=utf-8",
+			Format:      errorsBody,
+		},
+		ErrorCodes: []errcode.ErrorCode{
+			errcode.ErrorCodeTooManyRequests,
+		},
+	}
 )
 
 const (
@@ -202,17 +223,6 @@ const (
         ...
     ]
 }`
-
-	unauthorizedErrorsBody = `{
-	"errors:" [
-	    {
-            "code": "UNAUTHORIZED",
-            "message": "access to the requested resource is not authorized",
-            "detail": ...
-        },
-        ...
-    ]
-}`
 )
 
 // APIDescriptor exports descriptions of the layout of the v2 registry API.
@@ -391,6 +401,7 @@ var routeDescriptors = []RouteDescriptor{
 								StatusCode:  http.StatusNotFound,
 							},
 							unauthorizedResponseDescriptor,
+							tooManyRequestsDescriptor,
 						},
 					},
 				},
@@ -445,6 +456,7 @@ var routeDescriptors = []RouteDescriptor{
 							unauthorizedResponseDescriptor,
 							repositoryNotFoundResponseDescriptor,
 							deniedResponseDescriptor,
+							tooManyRequestsDescriptor,
 						},
 					},
 					{
@@ -481,6 +493,7 @@ var routeDescriptors = []RouteDescriptor{
 							unauthorizedResponseDescriptor,
 							repositoryNotFoundResponseDescriptor,
 							deniedResponseDescriptor,
+							tooManyRequestsDescriptor,
 						},
 					},
 				},
@@ -535,6 +548,7 @@ var routeDescriptors = []RouteDescriptor{
 							unauthorizedResponseDescriptor,
 							repositoryNotFoundResponseDescriptor,
 							deniedResponseDescriptor,
+							tooManyRequestsDescriptor,
 						},
 					},
 				},
@@ -592,6 +606,7 @@ var routeDescriptors = []RouteDescriptor{
 							unauthorizedResponseDescriptor,
 							repositoryNotFoundResponseDescriptor,
 							deniedResponseDescriptor,
+							tooManyRequestsDescriptor,
 							{
 								Name:        "Missing Layer(s)",
 								Description: "One or more layers may be missing during a manifest upload. If so, the missing layers will be enumerated in the error response.",
@@ -661,6 +676,7 @@ var routeDescriptors = []RouteDescriptor{
 							unauthorizedResponseDescriptor,
 							repositoryNotFoundResponseDescriptor,
 							deniedResponseDescriptor,
+							tooManyRequestsDescriptor,
 							{
 								Name:        "Unknown Manifest",
 								Description: "The specified `name` or `reference` are unknown to the registry and the delete was unable to proceed. Clients can assume the manifest was already deleted if this response is returned.",
@@ -769,6 +785,7 @@ var routeDescriptors = []RouteDescriptor{
 							unauthorizedResponseDescriptor,
 							repositoryNotFoundResponseDescriptor,
 							deniedResponseDescriptor,
+							tooManyRequestsDescriptor,
 						},
 					},
 					{
@@ -843,6 +860,7 @@ var routeDescriptors = []RouteDescriptor{
 							unauthorizedResponseDescriptor,
 							repositoryNotFoundResponseDescriptor,
 							deniedResponseDescriptor,
+							tooManyRequestsDescriptor,
 						},
 					},
 				},
@@ -909,6 +927,7 @@ var routeDescriptors = []RouteDescriptor{
 							unauthorizedResponseDescriptor,
 							repositoryNotFoundResponseDescriptor,
 							deniedResponseDescriptor,
+							tooManyRequestsDescriptor,
 						},
 					},
 				},
@@ -993,6 +1012,7 @@ var routeDescriptors = []RouteDescriptor{
 							unauthorizedResponseDescriptor,
 							repositoryNotFoundResponseDescriptor,
 							deniedResponseDescriptor,
+							tooManyRequestsDescriptor,
 						},
 					},
 					{
@@ -1039,6 +1059,7 @@ var routeDescriptors = []RouteDescriptor{
 							unauthorizedResponseDescriptor,
 							repositoryNotFoundResponseDescriptor,
 							deniedResponseDescriptor,
+							tooManyRequestsDescriptor,
 						},
 					},
 					{
@@ -1103,6 +1124,7 @@ var routeDescriptors = []RouteDescriptor{
 							unauthorizedResponseDescriptor,
 							repositoryNotFoundResponseDescriptor,
 							deniedResponseDescriptor,
+							tooManyRequestsDescriptor,
 						},
 					},
 				},
@@ -1175,6 +1197,7 @@ var routeDescriptors = []RouteDescriptor{
 							unauthorizedResponseDescriptor,
 							repositoryNotFoundResponseDescriptor,
 							deniedResponseDescriptor,
+							tooManyRequestsDescriptor,
 						},
 					},
 				},
@@ -1249,6 +1272,7 @@ var routeDescriptors = []RouteDescriptor{
 							unauthorizedResponseDescriptor,
 							repositoryNotFoundResponseDescriptor,
 							deniedResponseDescriptor,
+							tooManyRequestsDescriptor,
 						},
 					},
 					{
@@ -1334,6 +1358,7 @@ var routeDescriptors = []RouteDescriptor{
 							unauthorizedResponseDescriptor,
 							repositoryNotFoundResponseDescriptor,
 							deniedResponseDescriptor,
+							tooManyRequestsDescriptor,
 						},
 					},
 				},
@@ -1424,6 +1449,7 @@ var routeDescriptors = []RouteDescriptor{
 							unauthorizedResponseDescriptor,
 							repositoryNotFoundResponseDescriptor,
 							deniedResponseDescriptor,
+							tooManyRequestsDescriptor,
 						},
 					},
 				},
@@ -1480,6 +1506,7 @@ var routeDescriptors = []RouteDescriptor{
 							unauthorizedResponseDescriptor,
 							repositoryNotFoundResponseDescriptor,
 							deniedResponseDescriptor,
+							tooManyRequestsDescriptor,
 						},
 					},
 				},