diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json
index 23cf9e0f52f..02b632f57de 100644
--- a/api/openapi-spec/swagger.json
+++ b/api/openapi-spec/swagger.json
@@ -61376,7 +61376,7 @@
"type": "string"
},
"retryAfterSeconds": {
- "description": "If specified, the time in seconds before the operation should be retried.",
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action.",
"type": "integer",
"format": "int32"
},
diff --git a/api/swagger-spec/admissionregistration.k8s.io_v1alpha1.json b/api/swagger-spec/admissionregistration.k8s.io_v1alpha1.json
index 728467e6158..f6d28b231b0 100644
--- a/api/swagger-spec/admissionregistration.k8s.io_v1alpha1.json
+++ b/api/swagger-spec/admissionregistration.k8s.io_v1alpha1.json
@@ -1546,7 +1546,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/apps_v1beta1.json b/api/swagger-spec/apps_v1beta1.json
index 3d19866302d..5524e1f712d 100644
--- a/api/swagger-spec/apps_v1beta1.json
+++ b/api/swagger-spec/apps_v1beta1.json
@@ -3460,7 +3460,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/apps_v1beta2.json b/api/swagger-spec/apps_v1beta2.json
index 0977ae02c09..dec3f47f914 100644
--- a/api/swagger-spec/apps_v1beta2.json
+++ b/api/swagger-spec/apps_v1beta2.json
@@ -4812,7 +4812,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/authentication.k8s.io_v1.json b/api/swagger-spec/authentication.k8s.io_v1.json
index 2cf3b808f12..ee9a1527afc 100644
--- a/api/swagger-spec/authentication.k8s.io_v1.json
+++ b/api/swagger-spec/authentication.k8s.io_v1.json
@@ -336,7 +336,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/authentication.k8s.io_v1beta1.json b/api/swagger-spec/authentication.k8s.io_v1beta1.json
index fbc0e8b0313..5dfe2af2d9c 100644
--- a/api/swagger-spec/authentication.k8s.io_v1beta1.json
+++ b/api/swagger-spec/authentication.k8s.io_v1beta1.json
@@ -336,7 +336,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/authorization.k8s.io_v1.json b/api/swagger-spec/authorization.k8s.io_v1.json
index e152b05ecb1..e5c42d1eede 100644
--- a/api/swagger-spec/authorization.k8s.io_v1.json
+++ b/api/swagger-spec/authorization.k8s.io_v1.json
@@ -434,7 +434,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/authorization.k8s.io_v1beta1.json b/api/swagger-spec/authorization.k8s.io_v1beta1.json
index 1dad0a04770..915a081db69 100644
--- a/api/swagger-spec/authorization.k8s.io_v1beta1.json
+++ b/api/swagger-spec/authorization.k8s.io_v1beta1.json
@@ -434,7 +434,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/autoscaling_v1.json b/api/swagger-spec/autoscaling_v1.json
index d4ec040026e..58c6b78d36f 100644
--- a/api/swagger-spec/autoscaling_v1.json
+++ b/api/swagger-spec/autoscaling_v1.json
@@ -1343,7 +1343,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/autoscaling_v2alpha1.json b/api/swagger-spec/autoscaling_v2alpha1.json
index 3c84e006708..032683bad37 100644
--- a/api/swagger-spec/autoscaling_v2alpha1.json
+++ b/api/swagger-spec/autoscaling_v2alpha1.json
@@ -1343,7 +1343,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/batch_v1.json b/api/swagger-spec/batch_v1.json
index 9e14a0ac33e..33efe7cb224 100644
--- a/api/swagger-spec/batch_v1.json
+++ b/api/swagger-spec/batch_v1.json
@@ -1343,7 +1343,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/batch_v2alpha1.json b/api/swagger-spec/batch_v2alpha1.json
index 88c183d4ee8..3a9c6a88db8 100644
--- a/api/swagger-spec/batch_v2alpha1.json
+++ b/api/swagger-spec/batch_v2alpha1.json
@@ -2369,7 +2369,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/certificates.k8s.io_v1beta1.json b/api/swagger-spec/certificates.k8s.io_v1beta1.json
index 36d0fc508b7..99d663d81a7 100644
--- a/api/swagger-spec/certificates.k8s.io_v1beta1.json
+++ b/api/swagger-spec/certificates.k8s.io_v1beta1.json
@@ -1034,7 +1034,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/extensions_v1beta1.json b/api/swagger-spec/extensions_v1beta1.json
index 504cf1da6aa..2c74fe32ae9 100644
--- a/api/swagger-spec/extensions_v1beta1.json
+++ b/api/swagger-spec/extensions_v1beta1.json
@@ -6453,7 +6453,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/networking.k8s.io_v1.json b/api/swagger-spec/networking.k8s.io_v1.json
index da0e380b9d3..79a9ac80cb3 100644
--- a/api/swagger-spec/networking.k8s.io_v1.json
+++ b/api/swagger-spec/networking.k8s.io_v1.json
@@ -1174,7 +1174,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/policy_v1beta1.json b/api/swagger-spec/policy_v1beta1.json
index e857130a7d1..10511c69120 100644
--- a/api/swagger-spec/policy_v1beta1.json
+++ b/api/swagger-spec/policy_v1beta1.json
@@ -1340,7 +1340,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/rbac.authorization.k8s.io_v1alpha1.json b/api/swagger-spec/rbac.authorization.k8s.io_v1alpha1.json
index 7166cfd015f..6082897a705 100644
--- a/api/swagger-spec/rbac.authorization.k8s.io_v1alpha1.json
+++ b/api/swagger-spec/rbac.authorization.k8s.io_v1alpha1.json
@@ -3212,7 +3212,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/rbac.authorization.k8s.io_v1beta1.json b/api/swagger-spec/rbac.authorization.k8s.io_v1beta1.json
index 681eb673d1f..7a863a59cb3 100644
--- a/api/swagger-spec/rbac.authorization.k8s.io_v1beta1.json
+++ b/api/swagger-spec/rbac.authorization.k8s.io_v1beta1.json
@@ -3212,7 +3212,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/scheduling.k8s.io_v1alpha1.json b/api/swagger-spec/scheduling.k8s.io_v1alpha1.json
index 66635b1be61..90b531d57ea 100644
--- a/api/swagger-spec/scheduling.k8s.io_v1alpha1.json
+++ b/api/swagger-spec/scheduling.k8s.io_v1alpha1.json
@@ -940,7 +940,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/settings.k8s.io_v1alpha1.json b/api/swagger-spec/settings.k8s.io_v1alpha1.json
index 906485e9ac7..01f1f2ddbbb 100644
--- a/api/swagger-spec/settings.k8s.io_v1alpha1.json
+++ b/api/swagger-spec/settings.k8s.io_v1alpha1.json
@@ -1172,7 +1172,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/storage.k8s.io_v1.json b/api/swagger-spec/storage.k8s.io_v1.json
index 535b1283aee..f86ae454e38 100644
--- a/api/swagger-spec/storage.k8s.io_v1.json
+++ b/api/swagger-spec/storage.k8s.io_v1.json
@@ -935,7 +935,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/storage.k8s.io_v1beta1.json b/api/swagger-spec/storage.k8s.io_v1beta1.json
index a9a8f3f0791..31c31419f2c 100644
--- a/api/swagger-spec/storage.k8s.io_v1beta1.json
+++ b/api/swagger-spec/storage.k8s.io_v1beta1.json
@@ -935,7 +935,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/api/swagger-spec/v1.json b/api/swagger-spec/v1.json
index 84f650630fd..b7ee59b203d 100644
--- a/api/swagger-spec/v1.json
+++ b/api/swagger-spec/v1.json
@@ -17580,7 +17580,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/docs/api-reference/admissionregistration.k8s.io/v1alpha1/definitions.html b/docs/api-reference/admissionregistration.k8s.io/v1alpha1/definitions.html
index 2fbc1a8bc7f..e35dd956901 100755
--- a/docs/api-reference/admissionregistration.k8s.io/v1alpha1/definitions.html
+++ b/docs/api-reference/admissionregistration.k8s.io/v1alpha1/definitions.html
@@ -1182,7 +1182,7 @@ Depending on the enclosing object, subresources might not be allowed. Required.<
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/apps/v1beta1/definitions.html b/docs/api-reference/apps/v1beta1/definitions.html
index 8730ab176a4..e28807b9ddc 100755
--- a/docs/api-reference/apps/v1beta1/definitions.html
+++ b/docs/api-reference/apps/v1beta1/definitions.html
@@ -5337,7 +5337,7 @@ Examples:
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/apps/v1beta2/definitions.html b/docs/api-reference/apps/v1beta2/definitions.html
index abd552247cb..e358e64569d 100755
--- a/docs/api-reference/apps/v1beta2/definitions.html
+++ b/docs/api-reference/apps/v1beta2/definitions.html
@@ -5588,7 +5588,7 @@ Examples:
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/authentication.k8s.io/v1/definitions.html b/docs/api-reference/authentication.k8s.io/v1/definitions.html
index e31e008db4f..2962fcc672b 100755
--- a/docs/api-reference/authentication.k8s.io/v1/definitions.html
+++ b/docs/api-reference/authentication.k8s.io/v1/definitions.html
@@ -535,7 +535,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/authentication.k8s.io/v1beta1/definitions.html b/docs/api-reference/authentication.k8s.io/v1beta1/definitions.html
index 20cf0c87c7f..314dbeac33e 100755
--- a/docs/api-reference/authentication.k8s.io/v1beta1/definitions.html
+++ b/docs/api-reference/authentication.k8s.io/v1beta1/definitions.html
@@ -624,7 +624,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/authorization.k8s.io/v1/definitions.html b/docs/api-reference/authorization.k8s.io/v1/definitions.html
index 97f628970e2..cb8d7366268 100755
--- a/docs/api-reference/authorization.k8s.io/v1/definitions.html
+++ b/docs/api-reference/authorization.k8s.io/v1/definitions.html
@@ -617,7 +617,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/authorization.k8s.io/v1beta1/definitions.html b/docs/api-reference/authorization.k8s.io/v1beta1/definitions.html
index c3c38fabd1b..0bcba126523 100755
--- a/docs/api-reference/authorization.k8s.io/v1beta1/definitions.html
+++ b/docs/api-reference/authorization.k8s.io/v1beta1/definitions.html
@@ -541,7 +541,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/autoscaling/v1/definitions.html b/docs/api-reference/autoscaling/v1/definitions.html
index 5a8a9746248..a6ea7046bb5 100755
--- a/docs/api-reference/autoscaling/v1/definitions.html
+++ b/docs/api-reference/autoscaling/v1/definitions.html
@@ -668,7 +668,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/autoscaling/v2alpha1/definitions.html b/docs/api-reference/autoscaling/v2alpha1/definitions.html
index 70a3f818f37..b649bc388c5 100755
--- a/docs/api-reference/autoscaling/v2alpha1/definitions.html
+++ b/docs/api-reference/autoscaling/v2alpha1/definitions.html
@@ -1349,7 +1349,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/batch/v1/definitions.html b/docs/api-reference/batch/v1/definitions.html
index bd98808b311..41f42054280 100755
--- a/docs/api-reference/batch/v1/definitions.html
+++ b/docs/api-reference/batch/v1/definitions.html
@@ -4301,7 +4301,7 @@ Examples:
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/batch/v2alpha1/definitions.html b/docs/api-reference/batch/v2alpha1/definitions.html
index ca092fe8087..cf7bb70303e 100755
--- a/docs/api-reference/batch/v2alpha1/definitions.html
+++ b/docs/api-reference/batch/v2alpha1/definitions.html
@@ -4308,7 +4308,7 @@ Examples:
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/certificates.k8s.io/v1beta1/definitions.html b/docs/api-reference/certificates.k8s.io/v1beta1/definitions.html
index 2a47cb4534f..c682f7f589b 100755
--- a/docs/api-reference/certificates.k8s.io/v1beta1/definitions.html
+++ b/docs/api-reference/certificates.k8s.io/v1beta1/definitions.html
@@ -613,7 +613,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/extensions/v1beta1/definitions.html b/docs/api-reference/extensions/v1beta1/definitions.html
index c3dec2d21f1..40a6afd78f3 100755
--- a/docs/api-reference/extensions/v1beta1/definitions.html
+++ b/docs/api-reference/extensions/v1beta1/definitions.html
@@ -6070,7 +6070,7 @@ Both these may change in the future. Incoming requests are matched against the h
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/networking.k8s.io/v1/definitions.html b/docs/api-reference/networking.k8s.io/v1/definitions.html
index 955ff174bd9..eec98686c29 100755
--- a/docs/api-reference/networking.k8s.io/v1/definitions.html
+++ b/docs/api-reference/networking.k8s.io/v1/definitions.html
@@ -658,7 +658,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/policy/v1beta1/definitions.html b/docs/api-reference/policy/v1beta1/definitions.html
index 8841ef89a41..c4b3893b531 100755
--- a/docs/api-reference/policy/v1beta1/definitions.html
+++ b/docs/api-reference/policy/v1beta1/definitions.html
@@ -675,7 +675,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/rbac.authorization.k8s.io/v1alpha1/definitions.html b/docs/api-reference/rbac.authorization.k8s.io/v1alpha1/definitions.html
index 319f3ae3f99..935dc706cb8 100755
--- a/docs/api-reference/rbac.authorization.k8s.io/v1alpha1/definitions.html
+++ b/docs/api-reference/rbac.authorization.k8s.io/v1alpha1/definitions.html
@@ -1065,7 +1065,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/rbac.authorization.k8s.io/v1beta1/definitions.html b/docs/api-reference/rbac.authorization.k8s.io/v1beta1/definitions.html
index 31c4fa76915..ef23f83cc15 100755
--- a/docs/api-reference/rbac.authorization.k8s.io/v1beta1/definitions.html
+++ b/docs/api-reference/rbac.authorization.k8s.io/v1beta1/definitions.html
@@ -803,7 +803,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/scheduling.k8s.io/v1alpha1/definitions.html b/docs/api-reference/scheduling.k8s.io/v1alpha1/definitions.html
index c008fd569d1..d22e4c9e5c6 100755
--- a/docs/api-reference/scheduling.k8s.io/v1alpha1/definitions.html
+++ b/docs/api-reference/scheduling.k8s.io/v1alpha1/definitions.html
@@ -613,7 +613,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/settings.k8s.io/v1alpha1/definitions.html b/docs/api-reference/settings.k8s.io/v1alpha1/definitions.html
index 85ab797aab5..9b59e8f261a 100755
--- a/docs/api-reference/settings.k8s.io/v1alpha1/definitions.html
+++ b/docs/api-reference/settings.k8s.io/v1alpha1/definitions.html
@@ -1543,7 +1543,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/storage.k8s.io/v1/definitions.html b/docs/api-reference/storage.k8s.io/v1/definitions.html
index a230d5d93ae..19a38db5df4 100755
--- a/docs/api-reference/storage.k8s.io/v1/definitions.html
+++ b/docs/api-reference/storage.k8s.io/v1/definitions.html
@@ -613,7 +613,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/storage.k8s.io/v1beta1/definitions.html b/docs/api-reference/storage.k8s.io/v1beta1/definitions.html
index f45beab60ca..c55d3b0c6d2 100755
--- a/docs/api-reference/storage.k8s.io/v1beta1/definitions.html
+++ b/docs/api-reference/storage.k8s.io/v1beta1/definitions.html
@@ -668,7 +668,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/docs/api-reference/v1/definitions.html b/docs/api-reference/v1/definitions.html
index 3d3779e8105..9f1866413d2 100755
--- a/docs/api-reference/v1/definitions.html
+++ b/docs/api-reference/v1/definitions.html
@@ -6979,7 +6979,7 @@ Examples:
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/federation/apis/openapi-spec/swagger.json b/federation/apis/openapi-spec/swagger.json
index 9d80b7ac4e6..3348e64685e 100644
--- a/federation/apis/openapi-spec/swagger.json
+++ b/federation/apis/openapi-spec/swagger.json
@@ -13697,7 +13697,7 @@
"type": "string"
},
"retryAfterSeconds": {
- "description": "If specified, the time in seconds before the operation should be retried.",
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action.",
"type": "integer",
"format": "int32"
},
diff --git a/federation/apis/swagger-spec/extensions_v1beta1.json b/federation/apis/swagger-spec/extensions_v1beta1.json
index 5e1c5e1774c..6eac8ab38f1 100644
--- a/federation/apis/swagger-spec/extensions_v1beta1.json
+++ b/federation/apis/swagger-spec/extensions_v1beta1.json
@@ -4812,7 +4812,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/federation/apis/swagger-spec/federation_v1beta1.json b/federation/apis/swagger-spec/federation_v1beta1.json
index 0529718d95b..120831f1f8f 100644
--- a/federation/apis/swagger-spec/federation_v1beta1.json
+++ b/federation/apis/swagger-spec/federation_v1beta1.json
@@ -985,7 +985,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/federation/apis/swagger-spec/v1.json b/federation/apis/swagger-spec/v1.json
index bad86926c0f..ecff7047267 100644
--- a/federation/apis/swagger-spec/v1.json
+++ b/federation/apis/swagger-spec/v1.json
@@ -4652,7 +4652,7 @@
"retryAfterSeconds": {
"type": "integer",
"format": "int32",
- "description": "If specified, the time in seconds before the operation should be retried."
+ "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action."
}
}
},
diff --git a/federation/docs/api-reference/extensions/v1beta1/definitions.html b/federation/docs/api-reference/extensions/v1beta1/definitions.html
index c7592ccaa57..371167b51e8 100755
--- a/federation/docs/api-reference/extensions/v1beta1/definitions.html
+++ b/federation/docs/api-reference/extensions/v1beta1/definitions.html
@@ -5594,7 +5594,7 @@ Both these may change in the future. Incoming requests are matched against the h
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/federation/docs/api-reference/federation/v1beta1/definitions.html b/federation/docs/api-reference/federation/v1beta1/definitions.html
index 2d726cbba9d..46ac97d5946 100755
--- a/federation/docs/api-reference/federation/v1beta1/definitions.html
+++ b/federation/docs/api-reference/federation/v1beta1/definitions.html
@@ -709,7 +709,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/federation/docs/api-reference/v1/definitions.html b/federation/docs/api-reference/v1/definitions.html
index eb45dffacdb..155a431941e 100755
--- a/federation/docs/api-reference/v1/definitions.html
+++ b/federation/docs/api-reference/v1/definitions.html
@@ -1442,7 +1442,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
retryAfterSeconds |
-If specified, the time in seconds before the operation should be retried. |
+If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. |
false |
integer (int32) |
|
diff --git a/pkg/kubelet/server/BUILD b/pkg/kubelet/server/BUILD
index 94381c2f3c7..901302092a4 100644
--- a/pkg/kubelet/server/BUILD
+++ b/pkg/kubelet/server/BUILD
@@ -37,7 +37,6 @@ go_library(
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
"//vendor/github.com/prometheus/client_golang/prometheus/promhttp:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
@@ -79,7 +78,6 @@ go_test(
"//vendor/github.com/stretchr/testify/require:go_default_library",
"//vendor/golang.org/x/net/websocket:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/httpstream:go_default_library",
diff --git a/pkg/kubelet/server/server.go b/pkg/kubelet/server/server.go
index e728daaf784..74a5036828a 100644
--- a/pkg/kubelet/server/server.go
+++ b/pkg/kubelet/server/server.go
@@ -39,7 +39,6 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp"
"k8s.io/api/core/v1"
- apierrs "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -484,7 +483,7 @@ func (s *Server) getContainerLogs(request *restful.Request, response *restful.Re
}
logOptions.TypeMeta = metav1.TypeMeta{}
if errs := validation.ValidatePodLogOptions(logOptions); len(errs) > 0 {
- response.WriteError(apierrs.StatusUnprocessableEntity, fmt.Errorf(`{"message": "Invalid request."}`))
+ response.WriteError(http.StatusUnprocessableEntity, fmt.Errorf(`{"message": "Invalid request."}`))
return
}
diff --git a/pkg/kubelet/server/server_test.go b/pkg/kubelet/server/server_test.go
index 015947ddac4..b3b5ce9b46e 100644
--- a/pkg/kubelet/server/server_test.go
+++ b/pkg/kubelet/server/server_test.go
@@ -39,7 +39,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"k8s.io/api/core/v1"
- apierrs "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/httpstream"
@@ -1065,7 +1064,7 @@ func TestContainerLogsWithInvalidTail(t *testing.T) {
t.Errorf("Got error GETing: %v", err)
}
defer resp.Body.Close()
- if resp.StatusCode != apierrs.StatusUnprocessableEntity {
+ if resp.StatusCode != http.StatusUnprocessableEntity {
t.Errorf("Unexpected non-error reading container logs: %#v", resp)
}
}
diff --git a/pkg/registry/core/pod/storage/eviction.go b/pkg/registry/core/pod/storage/eviction.go
index 2c2d522bb91..468a25330ef 100644
--- a/pkg/registry/core/pod/storage/eviction.go
+++ b/pkg/registry/core/pod/storage/eviction.go
@@ -101,24 +101,9 @@ func (r *EvictionREST) Create(ctx genericapirequest.Context, obj runtime.Object,
// If it was false already, or if it becomes false during the course of our retries,
// raise an error marked as a 429.
- ok, err := r.checkAndDecrement(pod.Namespace, pod.Name, pdb)
- if err != nil {
+ if err := r.checkAndDecrement(pod.Namespace, pod.Name, pdb); err != nil {
return err
}
-
- if !ok {
- rtStatus = &metav1.Status{
- Status: metav1.StatusFailure,
- // TODO(mml): Include some more details about why the eviction is disallowed.
- // Ideally any such text is generated by the DisruptionController (offline).
- Message: "Cannot evict pod as it would violate the pod's disruption budget.",
- Code: 429,
- // TODO(mml): Add a Retry-After header. Once there are time-based
- // budgets, we can sometimes compute a sensible suggested value. But
- // even without that, we can give a suggestion (10 minutes?) that
- // prevents well-behaved clients from hammering us.
- }
- }
}
return nil
})
@@ -146,19 +131,28 @@ func (r *EvictionREST) Create(ctx genericapirequest.Context, obj runtime.Object,
}
// checkAndDecrement checks if the provided PodDisruptionBudget allows any disruption.
-func (r *EvictionREST) checkAndDecrement(namespace string, podName string, pdb policy.PodDisruptionBudget) (ok bool, err error) {
+func (r *EvictionREST) checkAndDecrement(namespace string, podName string, pdb policy.PodDisruptionBudget) error {
if pdb.Status.ObservedGeneration < pdb.Generation {
- return false, nil
+ // TODO(mml): Add a Retry-After header. Once there are time-based
+ // budgets, we can sometimes compute a sensible suggested value. But
+ // even without that, we can give a suggestion (10 minutes?) that
+ // prevents well-behaved clients from hammering us.
+ err := errors.NewTooManyRequests("Cannot evict pod as it would violate the pod's disruption budget.", 0)
+ err.ErrStatus.Details.Causes = append(err.ErrStatus.Details.Causes, metav1.StatusCause{Type: "DisruptionBudget", Message: fmt.Sprintf("The disruption budget %s is still being processed by the server.", pdb.Name)})
+ return err
}
if pdb.Status.PodDisruptionsAllowed < 0 {
- return false, errors.NewForbidden(policy.Resource("poddisruptionbudget"), pdb.Name, fmt.Errorf("pdb disruptions allowed is negative"))
+ return errors.NewForbidden(policy.Resource("poddisruptionbudget"), pdb.Name, fmt.Errorf("pdb disruptions allowed is negative"))
}
if len(pdb.Status.DisruptedPods) > MaxDisruptedPodSize {
- return false, errors.NewForbidden(policy.Resource("poddisruptionbudget"), pdb.Name, fmt.Errorf("DisrputedPods map too big - too many evictions not confirmed by PDB controller"))
+ return errors.NewForbidden(policy.Resource("poddisruptionbudget"), pdb.Name, fmt.Errorf("DisruptedPods map too big - too many evictions not confirmed by PDB controller"))
}
if pdb.Status.PodDisruptionsAllowed == 0 {
- return false, nil
+ err := errors.NewTooManyRequests("Cannot evict pod as it would violate the pod's disruption budget.", 0)
+ err.ErrStatus.Details.Causes = append(err.ErrStatus.Details.Causes, metav1.StatusCause{Type: "DisruptionBudget", Message: fmt.Sprintf("The disruption budget %s needs %d healthy pods and has %d currently", pdb.Name, pdb.Status.DesiredHealthy, pdb.Status.CurrentHealthy)})
+ return err
}
+
pdb.Status.PodDisruptionsAllowed--
if pdb.Status.DisruptedPods == nil {
pdb.Status.DisruptedPods = make(map[string]metav1.Time)
@@ -169,10 +163,10 @@ func (r *EvictionREST) checkAndDecrement(namespace string, podName string, pdb p
// be deleted at all and remove it from DisruptedPod map.
pdb.Status.DisruptedPods[podName] = metav1.Time{Time: time.Now()}
if _, err := r.podDisruptionBudgetClient.PodDisruptionBudgets(namespace).UpdateStatus(&pdb); err != nil {
- return false, err
+ return err
}
- return true, nil
+ return nil
}
// getPodDisruptionBudgets returns any PDBs that match the pod or err if there's an error.
diff --git a/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go b/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go
index 560c889b9c1..91975be85b3 100644
--- a/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go
+++ b/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go
@@ -28,16 +28,6 @@ import (
"k8s.io/apimachinery/pkg/util/validation/field"
)
-// HTTP Status codes not in the golang http package.
-const (
- StatusUnprocessableEntity = 422
- StatusTooManyRequests = 429
- // StatusServerTimeout is an indication that a transient server error has
- // occurred and the client *should* retry, with an optional Retry-After
- // header to specify the back off window.
- StatusServerTimeout = 504
-)
-
// StatusError is an error intended for consumption by a REST API server; it can also be
// reconstructed by clients from a REST response. Public to allow easy type switches.
type StatusError struct {
@@ -189,7 +179,7 @@ func NewInvalid(qualifiedKind schema.GroupKind, name string, errs field.ErrorLis
}
return &StatusError{metav1.Status{
Status: metav1.StatusFailure,
- Code: StatusUnprocessableEntity, // RFC 4918: StatusUnprocessableEntity
+ Code: http.StatusUnprocessableEntity,
Reason: metav1.StatusReasonInvalid,
Details: &metav1.StatusDetails{
Group: qualifiedKind.Group,
@@ -211,6 +201,21 @@ func NewBadRequest(reason string) *StatusError {
}}
}
+// NewTooManyRequests creates an error that indicates that the client must try again later because
+// the specified endpoint is not accepting requests. More specific details should be provided
+// if client should know why the failure was limited4.
+func NewTooManyRequests(message string, retryAfterSeconds int) *StatusError {
+ return &StatusError{metav1.Status{
+ Status: metav1.StatusFailure,
+ Code: http.StatusTooManyRequests,
+ Reason: metav1.StatusReasonTooManyRequests,
+ Message: message,
+ Details: &metav1.StatusDetails{
+ RetryAfterSeconds: int32(retryAfterSeconds),
+ },
+ }}
+}
+
// NewServiceUnavailable creates an error that indicates that the requested service is unavailable.
func NewServiceUnavailable(reason string) *StatusError {
return &StatusError{metav1.Status{
@@ -276,7 +281,7 @@ func NewInternalError(err error) *StatusError {
func NewTimeoutError(message string, retryAfterSeconds int) *StatusError {
return &StatusError{metav1.Status{
Status: metav1.StatusFailure,
- Code: StatusServerTimeout,
+ Code: http.StatusGatewayTimeout,
Reason: metav1.StatusReasonTimeout,
Message: fmt.Sprintf("Timeout: %s", message),
Details: &metav1.StatusDetails{
@@ -313,14 +318,14 @@ func NewGenericServerResponse(code int, verb string, qualifiedResource schema.Gr
case http.StatusMethodNotAllowed:
reason = metav1.StatusReasonMethodNotAllowed
message = "the server does not allow this method on the requested resource"
- case StatusUnprocessableEntity:
+ case http.StatusUnprocessableEntity:
reason = metav1.StatusReasonInvalid
message = "the server rejected our request due to an error in our request"
- case StatusServerTimeout:
- reason = metav1.StatusReasonServerTimeout
- message = "the server cannot complete the requested operation at this time, try again later"
- case StatusTooManyRequests:
+ case http.StatusGatewayTimeout:
reason = metav1.StatusReasonTimeout
+ message = "the server was unable to return a response in the time allotted, but may still be processing the request"
+ case http.StatusTooManyRequests:
+ reason = metav1.StatusReasonTooManyRequests
message = "the server has received too many requests and has asked us to try again later"
default:
if code >= 500 {
@@ -423,11 +428,13 @@ func IsInternalError(err error) bool {
// IsTooManyRequests determines if err is an error which indicates that there are too many requests
// that the server cannot handle.
-// TODO: update IsTooManyRequests() when the TooManyRequests(429) error returned from the API server has a non-empty Reason field
func IsTooManyRequests(err error) bool {
+ if reasonForError(err) == metav1.StatusReasonTooManyRequests {
+ return true
+ }
switch t := err.(type) {
case APIStatus:
- return t.Status().Code == StatusTooManyRequests
+ return t.Status().Code == http.StatusTooManyRequests
}
return false
}
@@ -455,13 +462,20 @@ func IsUnexpectedObjectError(err error) bool {
}
// SuggestsClientDelay returns true if this error suggests a client delay as well as the
-// suggested seconds to wait, or false if the error does not imply a wait.
+// suggested seconds to wait, or false if the error does not imply a wait. It does not
+// address whether the error *should* be retried, since some errors (like a 3xx) may
+// request delay without retry.
func SuggestsClientDelay(err error) (int, bool) {
switch t := err.(type) {
case APIStatus:
if t.Status().Details != nil {
switch t.Status().Reason {
- case metav1.StatusReasonServerTimeout, metav1.StatusReasonTimeout:
+ // this StatusReason explicitly requests the caller to delay the action
+ case metav1.StatusReasonServerTimeout:
+ return int(t.Status().Details.RetryAfterSeconds), true
+ }
+ // If the client requests that we retry after a certain number of seconds
+ if t.Status().Details.RetryAfterSeconds > 0 {
return int(t.Status().Details.RetryAfterSeconds), true
}
}
diff --git a/staging/src/k8s.io/apimachinery/pkg/api/errors/errors_test.go b/staging/src/k8s.io/apimachinery/pkg/api/errors/errors_test.go
index ab14e7af9a1..afc26fd31c4 100644
--- a/staging/src/k8s.io/apimachinery/pkg/api/errors/errors_test.go
+++ b/staging/src/k8s.io/apimachinery/pkg/api/errors/errors_test.go
@@ -83,15 +83,34 @@ func TestErrorNew(t *testing.T) {
if !IsServerTimeout(NewServerTimeout(resource("tests"), "reason", 0)) {
t.Errorf("expected to be %s", metav1.StatusReasonServerTimeout)
}
- if time, ok := SuggestsClientDelay(NewServerTimeout(resource("tests"), "doing something", 10)); time != 10 || !ok {
- t.Errorf("expected to be %s", metav1.StatusReasonServerTimeout)
- }
- if time, ok := SuggestsClientDelay(NewTimeoutError("test reason", 10)); time != 10 || !ok {
- t.Errorf("expected to be %s", metav1.StatusReasonTimeout)
- }
if !IsMethodNotSupported(NewMethodNotSupported(resource("foos"), "delete")) {
t.Errorf("expected to be %s", metav1.StatusReasonMethodNotAllowed)
}
+
+ if time, ok := SuggestsClientDelay(NewServerTimeout(resource("tests"), "doing something", 10)); time != 10 || !ok {
+ t.Errorf("unexpected %d", time)
+ }
+ if time, ok := SuggestsClientDelay(NewServerTimeout(resource("tests"), "doing something", 0)); time != 0 || !ok {
+ t.Errorf("unexpected %d", time)
+ }
+ if time, ok := SuggestsClientDelay(NewTimeoutError("test reason", 10)); time != 10 || !ok {
+ t.Errorf("unexpected %d", time)
+ }
+ if time, ok := SuggestsClientDelay(NewTooManyRequests("doing something", 10)); time != 10 || !ok {
+ t.Errorf("unexpected %d", time)
+ }
+ if time, ok := SuggestsClientDelay(NewTooManyRequests("doing something", 1)); time != 1 || !ok {
+ t.Errorf("unexpected %d", time)
+ }
+ if time, ok := SuggestsClientDelay(NewGenericServerResponse(429, "get", resource("tests"), "test", "doing something", 10, true)); time != 10 || !ok {
+ t.Errorf("unexpected %d", time)
+ }
+ if time, ok := SuggestsClientDelay(NewGenericServerResponse(500, "get", resource("tests"), "test", "doing something", 10, true)); time != 10 || !ok {
+ t.Errorf("unexpected %d", time)
+ }
+ if time, ok := SuggestsClientDelay(NewGenericServerResponse(429, "get", resource("tests"), "test", "doing something", 0, true)); time != 0 || ok {
+ t.Errorf("unexpected %d", time)
+ }
}
func TestNewInvalid(t *testing.T) {
diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto
index 9355a13092d..1362b4d42cd 100644
--- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto
+++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto
@@ -678,7 +678,9 @@ message StatusDetails {
// +optional
repeated StatusCause causes = 4;
- // If specified, the time in seconds before the operation should be retried.
+ // If specified, the time in seconds before the operation should be retried. Some errors may indicate
+ // the client must take an alternate action - for those errors this field may indicate how long to wait
+ // before taking the alternate action.
// +optional
optional int32 retryAfterSeconds = 5;
}
diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go
index 14c7255c92b..2e709b64986 100644
--- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go
+++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go
@@ -481,7 +481,9 @@ type StatusDetails struct {
// failure. Not all StatusReasons may provide detailed causes.
// +optional
Causes []StatusCause `json:"causes,omitempty" protobuf:"bytes,4,rep,name=causes"`
- // If specified, the time in seconds before the operation should be retried.
+ // If specified, the time in seconds before the operation should be retried. Some errors may indicate
+ // the client must take an alternate action - for those errors this field may indicate how long to wait
+ // before taking the alternate action.
// +optional
RetryAfterSeconds int32 `json:"retryAfterSeconds,omitempty" protobuf:"varint,5,opt,name=retryAfterSeconds"`
}
@@ -586,6 +588,15 @@ const (
// Status code 504
StatusReasonTimeout StatusReason = "Timeout"
+ // StatusReasonTooManyRequests means the server experienced too many requests within a
+ // given window and that the client must wait to perform the action again. A client may
+ // always retry the request that led to this error, although the client should wait at least
+ // the number of seconds specified by the retryAfterSeconds field.
+ // Details (optional):
+ // "retryAfterSeconds" int32 - the number of seconds before the operation should be retried
+ // Status code 429
+ StatusReasonTooManyRequests StatusReason = "TooManyRequests"
+
// StatusReasonBadRequest means that the request itself was invalid, because the request
// doesn't make any sense, for example deleting a read-only object. This is different than
// StatusReasonInvalid above which indicates that the API call could possibly succeed, but the
diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go
index 159164d7c95..62860a27c6b 100644
--- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go
+++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types_swagger_doc_generated.go
@@ -295,7 +295,7 @@ var map_StatusDetails = map[string]string{
"kind": "The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds",
"uid": "UID of the resource. (when there is a single resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids",
"causes": "The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes.",
- "retryAfterSeconds": "If specified, the time in seconds before the operation should be retried.",
+ "retryAfterSeconds": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action.",
}
func (StatusDetails) SwaggerDoc() map[string]string {
diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go
index 19980d543d1..361cb56d07b 100644
--- a/staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go
+++ b/staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go
@@ -3749,7 +3749,7 @@ func TestCreateTimeout(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
- itemOut := expectApiStatus(t, "POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo?timeout=4ms", data, apierrs.StatusServerTimeout)
+ itemOut := expectApiStatus(t, "POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo?timeout=4ms", data, http.StatusGatewayTimeout)
if itemOut.Status != metav1.StatusFailure || itemOut.Reason != metav1.StatusReasonTimeout {
t.Errorf("Unexpected status %#v", itemOut)
}
diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go
index 19515f5bf2c..5802aeb97d9 100644
--- a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go
+++ b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go
@@ -511,7 +511,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
// http.StatusUnsupportedMediaType, http.StatusNotAcceptable,
// http.StatusBadRequest, http.StatusUnauthorized, http.StatusForbidden,
// http.StatusRequestTimeout, http.StatusConflict, http.StatusPreconditionFailed,
- // 422 (StatusUnprocessableEntity), http.StatusInternalServerError,
+ // http.StatusUnprocessableEntity, http.StatusInternalServerError,
// http.StatusServiceUnavailable
// and api error codes
// Note that if we specify a versioned Status object here, we may need to
diff --git a/staging/src/k8s.io/apiserver/pkg/server/filters/BUILD b/staging/src/k8s.io/apiserver/pkg/server/filters/BUILD
index 5eede2d712c..ac14d153d67 100644
--- a/staging/src/k8s.io/apiserver/pkg/server/filters/BUILD
+++ b/staging/src/k8s.io/apiserver/pkg/server/filters/BUILD
@@ -46,7 +46,6 @@ go_library(
"//vendor/github.com/emicklei/go-restful:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
- "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
diff --git a/staging/src/k8s.io/apiserver/pkg/server/filters/maxinflight.go b/staging/src/k8s.io/apiserver/pkg/server/filters/maxinflight.go
index 3e159c21f28..8a1773df7e9 100644
--- a/staging/src/k8s.io/apiserver/pkg/server/filters/maxinflight.go
+++ b/staging/src/k8s.io/apiserver/pkg/server/filters/maxinflight.go
@@ -22,7 +22,6 @@ import (
"strings"
"time"
- "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/endpoints/metrics"
@@ -113,7 +112,11 @@ func WithMaxInFlightLimit(
if requestInfo.Namespace != "" {
scope = "namespace"
}
- metrics.MonitorRequest(r, strings.ToUpper(requestInfo.Verb), requestInfo.Resource, requestInfo.Subresource, "", scope, errors.StatusTooManyRequests, 0, time.Now())
+ if requestInfo.IsResourceRequest {
+ metrics.MonitorRequest(r, strings.ToUpper(requestInfo.Verb), requestInfo.Resource, requestInfo.Subresource, "", scope, http.StatusTooManyRequests, 0, time.Now())
+ } else {
+ metrics.MonitorRequest(r, strings.ToUpper(requestInfo.Verb), "", requestInfo.Path, "", scope, http.StatusTooManyRequests, 0, time.Now())
+ }
tooManyRequests(r, w)
}
}
@@ -123,5 +126,5 @@ func WithMaxInFlightLimit(
func tooManyRequests(req *http.Request, w http.ResponseWriter) {
// Return a 429 status indicating "Too Many Requests"
w.Header().Set("Retry-After", retryAfter)
- http.Error(w, "Too many requests, please try again later.", errors.StatusTooManyRequests)
+ http.Error(w, "Too many requests, please try again later.", http.StatusTooManyRequests)
}
diff --git a/staging/src/k8s.io/apiserver/pkg/server/filters/maxinflight_test.go b/staging/src/k8s.io/apiserver/pkg/server/filters/maxinflight_test.go
index 79e185e818c..fc302b22b4f 100644
--- a/staging/src/k8s.io/apiserver/pkg/server/filters/maxinflight_test.go
+++ b/staging/src/k8s.io/apiserver/pkg/server/filters/maxinflight_test.go
@@ -24,7 +24,6 @@ import (
"sync"
"testing"
- "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/authentication/user"
apifilters "k8s.io/apiserver/pkg/endpoints/filters"
@@ -148,7 +147,7 @@ func TestMaxInFlightNonMutating(t *testing.T) {
// Do this multiple times to show that rate limit rejected requests don't block.
for i := 0; i < 2; i++ {
- if err := expectHTTPGet(server.URL, errors.StatusTooManyRequests); err != nil {
+ if err := expectHTTPGet(server.URL, http.StatusTooManyRequests); err != nil {
t.Error(err)
}
}
@@ -213,7 +212,7 @@ func TestMaxInFlightMutating(t *testing.T) {
// Do this multiple times to show that rate limit rejected requests don't block.
for i := 0; i < 2; i++ {
- if err := expectHTTPPost(server.URL+"/foo/bar/", errors.StatusTooManyRequests); err != nil {
+ if err := expectHTTPPost(server.URL+"/foo/bar/", http.StatusTooManyRequests); err != nil {
t.Error(err)
}
}
diff --git a/staging/src/k8s.io/apiserver/pkg/server/filters/timeout.go b/staging/src/k8s.io/apiserver/pkg/server/filters/timeout.go
index e3e21a5f031..1e13f247f03 100644
--- a/staging/src/k8s.io/apiserver/pkg/server/filters/timeout.go
+++ b/staging/src/k8s.io/apiserver/pkg/server/filters/timeout.go
@@ -27,7 +27,6 @@ import (
"time"
apierrors "k8s.io/apimachinery/pkg/api/errors"
- "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/endpoints/metrics"
apirequest "k8s.io/apiserver/pkg/endpoints/request"
)
@@ -64,9 +63,13 @@ func WithTimeoutForNonLongRunningRequests(handler http.Handler, requestContextMa
if requestInfo.Namespace != "" {
scope = "namespace"
}
- metrics.MonitorRequest(req, strings.ToUpper(requestInfo.Verb), requestInfo.Resource, requestInfo.Subresource, "", scope, http.StatusInternalServerError, 0, now)
+ if requestInfo.IsResourceRequest {
+ metrics.MonitorRequest(req, strings.ToUpper(requestInfo.Verb), requestInfo.Resource, requestInfo.Subresource, "", scope, http.StatusGatewayTimeout, 0, now)
+ } else {
+ metrics.MonitorRequest(req, strings.ToUpper(requestInfo.Verb), "", requestInfo.Path, "", scope, http.StatusGatewayTimeout, 0, now)
+ }
}
- return time.After(globalTimeout), metricFn, apierrors.NewServerTimeout(schema.GroupResource{Group: requestInfo.APIGroup, Resource: requestInfo.Resource}, requestInfo.Verb, 0)
+ return time.After(globalTimeout), metricFn, apierrors.NewTimeoutError(fmt.Sprintf("request did not complete within %s", globalTimeout), 0)
}
return WithTimeout(handler, timeoutFunc)
}
@@ -74,7 +77,7 @@ func WithTimeoutForNonLongRunningRequests(handler http.Handler, requestContextMa
// WithTimeout returns an http.Handler that runs h with a timeout
// determined by timeoutFunc. The new http.Handler calls h.ServeHTTP to handle
// each request, but if a call runs for longer than its time limit, the
-// handler responds with a 503 Service Unavailable error and the message
+// handler responds with a 504 Gateway Timeout error and the message
// provided. (If msg is empty, a suitable default message will be sent.) After
// the handler times out, writes by h to its http.ResponseWriter will return
// http.ErrHandlerTimeout. If timeoutFunc returns a nil timeout channel, no
diff --git a/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook.go b/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook.go
index 4f03b50e74b..b1a897a193a 100755
--- a/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook.go
+++ b/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook.go
@@ -90,6 +90,11 @@ func WithExponentialBackoff(initialBackoff time.Duration, webhookFn func() error
var err error
wait.ExponentialBackoff(backoff, func() (bool, error) {
err = webhookFn()
+ // these errors indicate a need to retry an authentication check
+ if apierrors.IsServerTimeout(err) || apierrors.IsTimeout(err) || apierrors.IsTooManyRequests(err) {
+ return false, nil
+ }
+ // if the error sends the Retry-After header, we respect it as an explicit confirmation we should retry.
if _, shouldRetry := apierrors.SuggestsClientDelay(err); shouldRetry {
return false, nil
}
diff --git a/staging/src/k8s.io/client-go/rest/request.go b/staging/src/k8s.io/client-go/rest/request.go
index b90984043e6..5e245aeba9e 100644
--- a/staging/src/k8s.io/client-go/rest/request.go
+++ b/staging/src/k8s.io/client-go/rest/request.go
@@ -889,7 +889,7 @@ func isTextResponse(resp *http.Response) bool {
func checkWait(resp *http.Response) (int, bool) {
switch r := resp.StatusCode; {
// any 500 error code and 429 can trigger a wait
- case r == errors.StatusTooManyRequests, r >= 500:
+ case r == http.StatusTooManyRequests, r >= 500:
default:
return 0, false
}
diff --git a/staging/src/k8s.io/client-go/rest/request_test.go b/staging/src/k8s.io/client-go/rest/request_test.go
index fa016dfe1ce..0691fc7260c 100755
--- a/staging/src/k8s.io/client-go/rest/request_test.go
+++ b/staging/src/k8s.io/client-go/rest/request_test.go
@@ -1130,7 +1130,7 @@ func TestCheckRetryClosesBody(t *testing.T) {
return
}
w.Header().Set("Retry-After", "1")
- http.Error(w, "Too many requests, please try again later.", apierrors.StatusTooManyRequests)
+ http.Error(w, "Too many requests, please try again later.", http.StatusTooManyRequests)
}))
defer testServer.Close()
@@ -1204,7 +1204,7 @@ func TestCheckRetryHandles429And5xx(t *testing.T) {
return
}
w.Header().Set("Retry-After", "0")
- w.WriteHeader([]int{apierrors.StatusTooManyRequests, 500, 501, 504}[count])
+ w.WriteHeader([]int{http.StatusTooManyRequests, 500, 501, 504}[count])
count++
}))
defer testServer.Close()
@@ -1234,7 +1234,7 @@ func BenchmarkCheckRetryClosesBody(b *testing.B) {
return
}
w.Header().Set("Retry-After", "0")
- w.WriteHeader(apierrors.StatusTooManyRequests)
+ w.WriteHeader(http.StatusTooManyRequests)
}))
defer testServer.Close()