POST /apis/extensions/v1beta1/namespaces/{namespace}/ingresses
@@ -6367,7 +6367,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index ca0d6a2a583..36e094b7b6a 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -1197,7 +1197,7 @@ } }, "post": { - "description": "create a Endpoints", + "description": "create Endpoints", "consumes": [ "*/*" ], @@ -1405,7 +1405,7 @@ } }, "delete": { - "description": "delete a Endpoints", + "description": "delete Endpoints", "consumes": [ "*/*" ], @@ -1580,7 +1580,7 @@ } }, "post": { - "description": "create a Event", + "description": "create an Event", "consumes": [ "*/*" ], @@ -1788,7 +1788,7 @@ } }, "delete": { - "description": "delete a Event", + "description": "delete an Event", "consumes": [ "*/*" ], @@ -3353,7 +3353,7 @@ }, "/api/v1/namespaces/{namespace}/pods/{name}/eviction": { "post": { - "description": "create eviction of a Eviction", + "description": "create eviction of an Eviction", "consumes": [ "*/*" ], @@ -20515,7 +20515,7 @@ } }, "post": { - "description": "create a Ingress", + "description": "create an Ingress", "consumes": [ "*/*" ], @@ -20723,7 +20723,7 @@ } }, "delete": { - "description": "delete a Ingress", + "description": "delete an Ingress", "consumes": [ "*/*" ], diff --git a/api/openapi-spec/v1.json b/api/openapi-spec/v1.json index 3469799b09e..674365ea964 100644 --- a/api/openapi-spec/v1.json +++ b/api/openapi-spec/v1.json @@ -1107,7 +1107,7 @@ } }, "post": { - "description": "create a Endpoints", + "description": "create Endpoints", "consumes": [ "*/*" ], @@ -1303,7 +1303,7 @@ } }, "delete": { - "description": "delete a Endpoints", + "description": "delete Endpoints", "consumes": [ "*/*" ], @@ -1469,7 +1469,7 @@ } }, "post": { - "description": "create a Event", + "description": "create an Event", "consumes": [ "*/*" ], @@ -1665,7 +1665,7 @@ } }, "delete": { - "description": "delete a Event", + "description": "delete an Event", "consumes": [ "*/*" ], @@ -3143,7 +3143,7 @@ }, "/api/v1/namespaces/{namespace}/pods/{name}/eviction": { "post": { - "description": "create eviction of a Eviction", + "description": "create eviction of an Eviction", "consumes": [ "*/*" ], diff --git a/api/swagger-spec/extensions_v1beta1.json b/api/swagger-spec/extensions_v1beta1.json index c4ab0557a34..944757e49f3 100644 --- a/api/swagger-spec/extensions_v1beta1.json +++ b/api/swagger-spec/extensions_v1beta1.json @@ -3184,7 +3184,7 @@ { "type": "v1beta1.Ingress", "method": "POST", - "summary": "create a Ingress", + "summary": "create an Ingress", "nickname": "createNamespacedIngress", "parameters": [ { @@ -3578,7 +3578,7 @@ { "type": "unversioned.Status", "method": "DELETE", - "summary": "delete a Ingress", + "summary": "delete an Ingress", "nickname": "deleteNamespacedIngress", "parameters": [ { diff --git a/api/swagger-spec/v1.json b/api/swagger-spec/v1.json index 801079faaff..726754cff3f 100644 --- a/api/swagger-spec/v1.json +++ b/api/swagger-spec/v1.json @@ -1062,7 +1062,7 @@ { "type": "v1.Endpoints", "method": "POST", - "summary": "create a Endpoints", + "summary": "create Endpoints", "nickname": "createNamespacedEndpoints", "parameters": [ { @@ -1456,7 +1456,7 @@ { "type": "unversioned.Status", "method": "DELETE", - "summary": "delete a Endpoints", + "summary": "delete Endpoints", "nickname": "deleteNamespacedEndpoints", "parameters": [ { @@ -1851,7 +1851,7 @@ { "type": "v1.Event", "method": "POST", - "summary": "create a Event", + "summary": "create an Event", "nickname": "createNamespacedEvent", "parameters": [ { @@ -2245,7 +2245,7 @@ { "type": "unversioned.Status", "method": "DELETE", - "summary": "delete a Event", + "summary": "delete an Event", "nickname": "deleteNamespacedEvent", "parameters": [ { @@ -8615,7 +8615,7 @@ { "type": "v1alpha1.Eviction", "method": "POST", - "summary": "create eviction of a Eviction", + "summary": "create eviction of an Eviction", "nickname": "createNamespacedEvictionEviction", "parameters": [ { diff --git a/docs/api-reference/extensions/v1beta1/operations.html b/docs/api-reference/extensions/v1beta1/operations.html index 6d214ce51d8..a4e68b78fcd 100755 --- a/docs/api-reference/extensions/v1beta1/operations.html +++ b/docs/api-reference/extensions/v1beta1/operations.html @@ -5986,7 +5986,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
POST /apis/extensions/v1beta1/namespaces/{namespace}/ingresses
@@ -6367,7 +6367,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
DELETE /apis/extensions/v1beta1/namespaces/{namespace}/ingresses/{name}
diff --git a/docs/api-reference/v1/operations.html b/docs/api-reference/v1/operations.html
index d29b3e3b51b..09f46e05d64 100755
--- a/docs/api-reference/v1/operations.html
+++ b/docs/api-reference/v1/operations.html
@@ -3078,7 +3078,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
POST /api/v1/namespaces/{namespace}/endpoints
@@ -3459,7 +3459,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
DELETE /api/v1/namespaces/{namespace}/endpoints/{name}
@@ -4027,7 +4027,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
POST /api/v1/namespaces/{namespace}/events
@@ -4408,7 +4408,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
DELETE /api/v1/namespaces/{namespace}/events/{name}
@@ -8311,7 +8311,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
POST /api/v1/namespaces/{namespace}/pods/{name}/eviction
diff --git a/federation/docs/api-reference/extensions/v1beta1/operations.html b/federation/docs/api-reference/extensions/v1beta1/operations.html
index 590926348d8..7c292ae5ea8 100755
--- a/federation/docs/api-reference/extensions/v1beta1/operations.html
+++ b/federation/docs/api-reference/extensions/v1beta1/operations.html
@@ -4360,7 +4360,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
POST /apis/extensions/v1beta1/namespaces/{namespace}/ingresses
@@ -4741,7 +4741,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
DELETE /apis/extensions/v1beta1/namespaces/{namespace}/ingresses/{name}
diff --git a/pkg/apiserver/BUILD b/pkg/apiserver/BUILD
index a37c91749ee..8981bc8d1d4 100644
--- a/pkg/apiserver/BUILD
+++ b/pkg/apiserver/BUILD
@@ -51,6 +51,7 @@ go_library(
"//pkg/util/proxy:go_default_library",
"//pkg/util/runtime:go_default_library",
"//pkg/util/strategicpatch:go_default_library",
+ "//pkg/util/strings:go_default_library",
"//pkg/util/wsstream:go_default_library",
"//pkg/watch:go_default_library",
"//pkg/watch/versioned:go_default_library",
diff --git a/pkg/apiserver/api_installer.go b/pkg/apiserver/api_installer.go
index a3920f2632c..d90beb8c332 100644
--- a/pkg/apiserver/api_installer.go
+++ b/pkg/apiserver/api_installer.go
@@ -34,6 +34,7 @@ import (
"k8s.io/kubernetes/pkg/apiserver/metrics"
"k8s.io/kubernetes/pkg/conversion"
"k8s.io/kubernetes/pkg/runtime"
+ utilstrings "k8s.io/kubernetes/pkg/util/strings"
"github.com/emicklei/go-restful"
)
@@ -610,9 +611,10 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
handler = CreateResource(creater, reqScope, a.group.Typer, admit)
}
handler = metrics.InstrumentRouteFunc(action.Verb, resource, handler)
- doc := "create a " + kind
+ article := utilstrings.GetArticleForNoun(kind, " ")
+ doc := "create" + article + kind
if hasSubresource {
- doc = "create " + subresource + " of a " + kind
+ doc = "create " + subresource + " of" + article + kind
}
route := ws.POST(action.Path).To(handler).
Doc(doc).
@@ -625,9 +627,10 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
addParams(route, action.Params)
ws.Route(route)
case "DELETE": // Delete a resource.
- doc := "delete a " + kind
+ article := utilstrings.GetArticleForNoun(kind, " ")
+ doc := "delete" + article + kind
if hasSubresource {
- doc = "delete " + subresource + " of a " + kind
+ doc = "delete " + subresource + " of" + article + kind
}
handler := metrics.InstrumentRouteFunc(action.Verb, resource, DeleteResource(gracefulDeleter, isGracefulDeleter, reqScope, admit))
route := ws.DELETE(action.Path).To(handler).
diff --git a/pkg/util/strings/strings.go b/pkg/util/strings/strings.go
index 2bcb174afc7..8de8619b343 100644
--- a/pkg/util/strings/strings.go
+++ b/pkg/util/strings/strings.go
@@ -17,8 +17,10 @@ limitations under the License.
package strings
import (
+ "fmt"
"path"
"strings"
+ "unicode"
)
// Splits a fully qualified name and returns its namespace and name.
@@ -45,3 +47,30 @@ func ShortenString(str string, n int) string {
return str[:n]
}
}
+
+// GetArticleForNoun returns the article needed for the given noun.
+func GetArticleForNoun(noun string, padding string) string {
+ if noun[len(noun)-2:] != "ss" && noun[len(noun)-1:] == "s" {
+ // Plurals don't have an article.
+ // Don't catch words like class
+ return fmt.Sprintf("%v", padding)
+ }
+
+ article := "a"
+ if isVowel(rune(noun[0])) {
+ article = "an"
+ }
+
+ return fmt.Sprintf("%s%s%s", padding, article, padding)
+}
+
+// isVowel returns true if the rune is a vowel (case insensitive).
+func isVowel(c rune) bool {
+ vowels := []rune{'a', 'e', 'i', 'o', 'u'}
+ for _, value := range vowels {
+ if value == unicode.ToLower(c) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/pkg/util/strings/strings_test.go b/pkg/util/strings/strings_test.go
index 13c72599565..c31ea5f5219 100644
--- a/pkg/util/strings/strings_test.go
+++ b/pkg/util/strings/strings_test.go
@@ -71,3 +71,73 @@ func TestShortenString(t *testing.T) {
}
}
}
+
+func TestIsVowel(t *testing.T) {
+ tests := []struct {
+ name string
+ arg rune
+ want bool
+ }{
+ {
+ name: "yes",
+ arg: 'E',
+ want: true,
+ },
+ {
+ name: "no",
+ arg: 'n',
+ want: false,
+ },
+ }
+ for _, tt := range tests {
+ if got := isVowel(tt.arg); got != tt.want {
+ t.Errorf("%q. IsVowel() = %v, want %v", tt.name, got, tt.want)
+ }
+ }
+}
+
+func TestGetArticleForNoun(t *testing.T) {
+ type args struct {
+ }
+ tests := []struct {
+ noun string
+ padding string
+ want string
+ }{
+ {
+ noun: "Frog",
+ padding: " ",
+ want: " a ",
+ },
+ {
+ noun: "frogs",
+ padding: " ",
+ want: " ",
+ },
+ {
+ noun: "apple",
+ padding: "",
+ want: "an",
+ },
+ {
+ noun: "Apples",
+ padding: " ",
+ want: " ",
+ },
+ {
+ noun: "Ingress",
+ padding: " ",
+ want: " an ",
+ },
+ {
+ noun: "Class",
+ padding: " ",
+ want: " a ",
+ },
+ }
+ for _, tt := range tests {
+ if got := GetArticleForNoun(tt.noun, tt.padding); got != tt.want {
+ t.Errorf("%q. GetArticleForNoun() = %v, want %v", tt.noun, got, tt.want)
+ }
+ }
+}