Merge pull request #118930 from atiratree/automated-cherry-pick-of-#118876-upstream-release-1.27
Automated cherry pick of #118876: kubectl explain should work for both cluster and namespace Kubernetes-commit: 04e86095d38aec469c31c9df707796ff7bf05de3
This commit is contained in:
commit
13f7b15bc1
4
go.mod
4
go.mod
|
|
@ -33,7 +33,7 @@ require (
|
|||
k8s.io/api v0.0.0-20230705181702-64b026215965
|
||||
k8s.io/apimachinery v0.0.0-20230612171306-38152d47d786
|
||||
k8s.io/cli-runtime v0.0.0-20230705200247-da2c5ab289b9
|
||||
k8s.io/client-go v0.0.0-20230705183358-8d8e2bc8c982
|
||||
k8s.io/client-go v0.0.0-20230705183401-860d25f20e24
|
||||
k8s.io/component-base v0.0.0-20230705190003-c964270bd046
|
||||
k8s.io/component-helpers v0.0.0-20230705190518-e8b08838a22f
|
||||
k8s.io/klog/v2 v2.90.1
|
||||
|
|
@ -97,7 +97,7 @@ replace (
|
|||
k8s.io/api => k8s.io/api v0.0.0-20230705181702-64b026215965
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20230612171306-38152d47d786
|
||||
k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20230705200247-da2c5ab289b9
|
||||
k8s.io/client-go => k8s.io/client-go v0.0.0-20230705183358-8d8e2bc8c982
|
||||
k8s.io/client-go => k8s.io/client-go v0.0.0-20230705183401-860d25f20e24
|
||||
k8s.io/code-generator => k8s.io/code-generator v0.0.0-20230705153058-ad209354fb6b
|
||||
k8s.io/component-base => k8s.io/component-base v0.0.0-20230705190003-c964270bd046
|
||||
k8s.io/component-helpers => k8s.io/component-helpers v0.0.0-20230705190518-e8b08838a22f
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -545,8 +545,8 @@ k8s.io/apimachinery v0.0.0-20230612171306-38152d47d786 h1:5apbbWoKi3ZjCSWm5UKfcN
|
|||
k8s.io/apimachinery v0.0.0-20230612171306-38152d47d786/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E=
|
||||
k8s.io/cli-runtime v0.0.0-20230705200247-da2c5ab289b9 h1:BfpceTxJkpRJ241YNDPtheyf2Ru/ACrDgSHHbKuYiIE=
|
||||
k8s.io/cli-runtime v0.0.0-20230705200247-da2c5ab289b9/go.mod h1:Dyr7YCfqajaLZf6BgME78H+mdgyIdE+3goKo6tXRBZU=
|
||||
k8s.io/client-go v0.0.0-20230705183358-8d8e2bc8c982 h1:d+jZBdBd2n2D7k/8+fizAqZXHBtCtWYXvtrAXQTNWUI=
|
||||
k8s.io/client-go v0.0.0-20230705183358-8d8e2bc8c982/go.mod h1:BuW1PoLqaULdxqGIXqc77od21c39c6Cxe+rm9KhNnvc=
|
||||
k8s.io/client-go v0.0.0-20230705183401-860d25f20e24 h1:h7JwteUItQCraRMQUdOoFve+0eiAR2IvUs0sXP/xWvg=
|
||||
k8s.io/client-go v0.0.0-20230705183401-860d25f20e24/go.mod h1:BuW1PoLqaULdxqGIXqc77od21c39c6Cxe+rm9KhNnvc=
|
||||
k8s.io/component-base v0.0.0-20230705190003-c964270bd046 h1:OBVR0/Wl6AP93SGN8cOtRJFmyHztwGU0rn6Cfj35p2c=
|
||||
k8s.io/component-base v0.0.0-20230705190003-c964270bd046/go.mod h1:iTsyaqmcZA6Cwc2WL21dLc0H8cCZZzwbklTzDQzuqvU=
|
||||
k8s.io/component-helpers v0.0.0-20230705190518-e8b08838a22f h1:aJREGrqWonsPU+rz6MItpzzgWvWKLtTaThx0HBr9kkg=
|
||||
|
|
|
|||
|
|
@ -185,6 +185,9 @@ func WithBuiltinTemplateFuncs(tmpl *template.Template) *template.Template {
|
|||
|
||||
return copyDict, nil
|
||||
},
|
||||
"list": func(values ...any) ([]any, error) {
|
||||
return values, nil
|
||||
},
|
||||
"add": func(value, operand int) int {
|
||||
return value + operand
|
||||
},
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -2,13 +2,33 @@
|
|||
{{- $prefix := (ternary "/api" (join "" "/apis/" $.GVR.Group) (not $.GVR.Group)) -}}
|
||||
|
||||
{{- /* Search both cluster-scoped and namespaced-scoped paths for the GVR to find its GVK */ -}}
|
||||
{{- /* Looks for path /apis/<group>/<version>/<resource> or /apis/<group>/<version>/<version>/namespaces/{namespace}/<resource> */ -}}
|
||||
{{- /* Also search for paths with {name} component in case the list path is missing */ -}}
|
||||
{{- /* Looks for the following paths: */ -}}
|
||||
{{- /* /apis/<group>/<version>/<resource> */ -}}
|
||||
{{- /* /apis/<group>/<version>/<resource>/{name} */ -}}
|
||||
{{- /* /apis/<group>/<version>/namespaces/{namespace}/<resource> */ -}}
|
||||
{{- /* /apis/<group>/<version>/namespaces/{namespace}/<resource>/{name} */ -}}
|
||||
{{- /* Also search for get verb paths in case list verb is missing */ -}}
|
||||
{{- $clusterScopedSearchPath := join "/" $prefix $.GVR.Version $.GVR.Resource -}}
|
||||
{{- $namespaceScopedSearchPath := join "/" $prefix $.GVR.Version "namespaces" "\\{namespace\\}" $.GVR.Resource -}}
|
||||
{{- $path := or (index $.Document "paths" $clusterScopedSearchPath) (index $.Document "paths" $clusterScopedSearchPath) -}}
|
||||
{{- $clusterScopedNameSearchPath := join "/" $prefix $.GVR.Version $.GVR.Resource "{name}" -}}
|
||||
{{- $namespaceScopedSearchPath := join "/" $prefix $.GVR.Version "namespaces" "{namespace}" $.GVR.Resource -}}
|
||||
{{- $namespaceScopedNameSearchPath := join "/" $prefix $.GVR.Version "namespaces" "{namespace}" $.GVR.Resource "{name}" -}}
|
||||
{{- $gvk := "" -}}
|
||||
|
||||
{{- /* Pull GVK from operation */ -}}
|
||||
{{- with $gvk := and $path (index $path "get" "x-kubernetes-group-version-kind") -}}
|
||||
{{- range $index, $searchPath := (list $clusterScopedSearchPath $clusterScopedNameSearchPath $namespaceScopedSearchPath $namespaceScopedNameSearchPath) -}}
|
||||
{{- with $resourcePathElement := index $.Document "paths" $searchPath -}}
|
||||
{{- range $methodIndex, $method := (list "get" "post" "put" "patch" "delete") -}}
|
||||
{{- with $resourceMethodPathElement := index $resourcePathElement $method -}}
|
||||
{{- with $gvk = index $resourceMethodPathElement "x-kubernetes-group-version-kind" -}}
|
||||
{{- break -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- with $gvk -}}
|
||||
{{- if $gvk.group -}}
|
||||
GROUP: {{ $gvk.group }}{{"\n" -}}
|
||||
{{- end -}}
|
||||
|
|
|
|||
|
|
@ -41,17 +41,46 @@ var (
|
|||
//go:embed apiextensions.k8s.io_v1.json
|
||||
apiextensionsJSON string
|
||||
|
||||
//go:embed batch.k8s.io_v1.json
|
||||
batchJSON string
|
||||
|
||||
apiExtensionsV1OpenAPI map[string]interface{} = func() map[string]interface{} {
|
||||
var res map[string]interface{}
|
||||
utilruntime.Must(json.Unmarshal([]byte(apiextensionsJSON), &res))
|
||||
return res
|
||||
}()
|
||||
|
||||
apiExtensionsV1OpenAPIWithoutListVerb map[string]interface{} = func() map[string]interface{} {
|
||||
var res map[string]interface{}
|
||||
utilruntime.Must(json.Unmarshal([]byte(apiextensionsJSON), &res))
|
||||
paths := res["paths"].(map[string]interface{})
|
||||
delete(paths, "/apis/apiextensions.k8s.io/v1/customresourcedefinitions")
|
||||
return res
|
||||
}()
|
||||
|
||||
apiExtensionsV1OpenAPISpec spec3.OpenAPI = func() spec3.OpenAPI {
|
||||
var res spec3.OpenAPI
|
||||
utilruntime.Must(json.Unmarshal([]byte(apiextensionsJSON), &res))
|
||||
return res
|
||||
}()
|
||||
|
||||
batchV1OpenAPI map[string]interface{} = func() map[string]interface{} {
|
||||
var res map[string]interface{}
|
||||
utilruntime.Must(json.Unmarshal([]byte(batchJSON), &res))
|
||||
return res
|
||||
}()
|
||||
|
||||
batchV1OpenAPIWithoutListVerb map[string]interface{} = func() map[string]interface{} {
|
||||
var res map[string]interface{}
|
||||
utilruntime.Must(json.Unmarshal([]byte(batchJSON), &res))
|
||||
paths := res["paths"].(map[string]interface{})
|
||||
delete(paths, "/apis/batch/v1/jobs")
|
||||
delete(paths, "/apis/batch/v1/namespaces/{namespace}/jobs")
|
||||
|
||||
delete(paths, "/apis/batch/v1/cronjobs")
|
||||
delete(paths, "/apis/batch/v1/namespaces/{namespace}/cronjobs/{name}")
|
||||
return res
|
||||
}()
|
||||
)
|
||||
|
||||
type testCase struct {
|
||||
|
|
@ -143,6 +172,74 @@ func TestPlaintext(t *testing.T) {
|
|||
checkContains("CustomResourceDefinition represents a resource that should be exposed"),
|
||||
},
|
||||
},
|
||||
{
|
||||
// Test basic ability to find a namespaced GVR and print its description
|
||||
Name: "SchemaFoundNamespaced",
|
||||
Context: v2.TemplateContext{
|
||||
Document: batchV1OpenAPI,
|
||||
GVR: schema.GroupVersionResource{
|
||||
Group: "batch",
|
||||
Version: "v1",
|
||||
Resource: "jobs",
|
||||
},
|
||||
FieldPath: nil,
|
||||
Recursive: false,
|
||||
},
|
||||
Checks: []check{
|
||||
checkContains("Job represents the configuration of a single job"),
|
||||
},
|
||||
},
|
||||
{
|
||||
// Test basic ability to find a GVR without a list verb and print its description
|
||||
Name: "SchemaFoundWithoutListVerb",
|
||||
Context: v2.TemplateContext{
|
||||
Document: apiExtensionsV1OpenAPIWithoutListVerb,
|
||||
GVR: schema.GroupVersionResource{
|
||||
Group: "apiextensions.k8s.io",
|
||||
Version: "v1",
|
||||
Resource: "customresourcedefinitions",
|
||||
},
|
||||
FieldPath: nil,
|
||||
Recursive: false,
|
||||
},
|
||||
Checks: []check{
|
||||
checkContains("CustomResourceDefinition represents a resource that should be exposed"),
|
||||
},
|
||||
},
|
||||
{
|
||||
// Test basic ability to find a namespaced GVR without a list verb and print its description
|
||||
Name: "SchemaFoundNamespacedWithoutListVerb",
|
||||
Context: v2.TemplateContext{
|
||||
Document: batchV1OpenAPIWithoutListVerb,
|
||||
GVR: schema.GroupVersionResource{
|
||||
Group: "batch",
|
||||
Version: "v1",
|
||||
Resource: "jobs",
|
||||
},
|
||||
FieldPath: nil,
|
||||
Recursive: false,
|
||||
},
|
||||
Checks: []check{
|
||||
checkContains("Job represents the configuration of a single job"),
|
||||
},
|
||||
},
|
||||
{
|
||||
// Test basic ability to find a namespaced GVR without a top level list verb and print its description
|
||||
Name: "SchemaFoundNamespacedWithoutTopLevelListVerb",
|
||||
Context: v2.TemplateContext{
|
||||
Document: batchV1OpenAPIWithoutListVerb,
|
||||
GVR: schema.GroupVersionResource{
|
||||
Group: "batch",
|
||||
Version: "v1",
|
||||
Resource: "cronjobs",
|
||||
},
|
||||
FieldPath: nil,
|
||||
Recursive: false,
|
||||
},
|
||||
Checks: []check{
|
||||
checkContains("CronJob represents the configuration of a single cron job"),
|
||||
},
|
||||
},
|
||||
{
|
||||
// Test that shows trying to find a non-existent field path of an existing
|
||||
// schema
|
||||
|
|
|
|||
Loading…
Reference in New Issue