mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
add kubectl api-resources command
This commit is contained in:
parent
11104d75f1
commit
110641b34c
@ -135,6 +135,7 @@ docs/man/man1/kubeadm.1
|
|||||||
docs/man/man1/kubectl-alpha-diff.1
|
docs/man/man1/kubectl-alpha-diff.1
|
||||||
docs/man/man1/kubectl-alpha.1
|
docs/man/man1/kubectl-alpha.1
|
||||||
docs/man/man1/kubectl-annotate.1
|
docs/man/man1/kubectl-annotate.1
|
||||||
|
docs/man/man1/kubectl-api-resources.1
|
||||||
docs/man/man1/kubectl-api-versions.1
|
docs/man/man1/kubectl-api-versions.1
|
||||||
docs/man/man1/kubectl-apply-edit-last-applied.1
|
docs/man/man1/kubectl-apply-edit-last-applied.1
|
||||||
docs/man/man1/kubectl-apply-set-last-applied.1
|
docs/man/man1/kubectl-apply-set-last-applied.1
|
||||||
@ -234,6 +235,7 @@ docs/user-guide/kubectl/kubectl.md
|
|||||||
docs/user-guide/kubectl/kubectl_alpha.md
|
docs/user-guide/kubectl/kubectl_alpha.md
|
||||||
docs/user-guide/kubectl/kubectl_alpha_diff.md
|
docs/user-guide/kubectl/kubectl_alpha_diff.md
|
||||||
docs/user-guide/kubectl/kubectl_annotate.md
|
docs/user-guide/kubectl/kubectl_annotate.md
|
||||||
|
docs/user-guide/kubectl/kubectl_api-resources.md
|
||||||
docs/user-guide/kubectl/kubectl_api-versions.md
|
docs/user-guide/kubectl/kubectl_api-versions.md
|
||||||
docs/user-guide/kubectl/kubectl_apply.md
|
docs/user-guide/kubectl/kubectl_apply.md
|
||||||
docs/user-guide/kubectl/kubectl_apply_edit-last-applied.md
|
docs/user-guide/kubectl/kubectl_apply_edit-last-applied.md
|
||||||
@ -329,6 +331,7 @@ docs/user-guide/kubectl/kubectl_version.md
|
|||||||
docs/yaml/kubectl/kubectl.yaml
|
docs/yaml/kubectl/kubectl.yaml
|
||||||
docs/yaml/kubectl/kubectl_alpha.yaml
|
docs/yaml/kubectl/kubectl_alpha.yaml
|
||||||
docs/yaml/kubectl/kubectl_annotate.yaml
|
docs/yaml/kubectl/kubectl_annotate.yaml
|
||||||
|
docs/yaml/kubectl/kubectl_api-resources.yaml
|
||||||
docs/yaml/kubectl/kubectl_api-versions.yaml
|
docs/yaml/kubectl/kubectl_api-versions.yaml
|
||||||
docs/yaml/kubectl/kubectl_apply.yaml
|
docs/yaml/kubectl/kubectl_apply.yaml
|
||||||
docs/yaml/kubectl/kubectl_attach.yaml
|
docs/yaml/kubectl/kubectl_attach.yaml
|
||||||
|
3
docs/man/man1/kubectl-api-resources.1
Normal file
3
docs/man/man1/kubectl-api-resources.1
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
This file is autogenerated, but we've stopped checking such files into the
|
||||||
|
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
|
||||||
|
populate this file.
|
3
docs/user-guide/kubectl/kubectl_api-resources.md
Normal file
3
docs/user-guide/kubectl/kubectl_api-resources.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
This file is autogenerated, but we've stopped checking such files into the
|
||||||
|
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
|
||||||
|
populate this file.
|
3
docs/yaml/kubectl/kubectl_api-resources.yaml
Normal file
3
docs/yaml/kubectl/kubectl_api-resources.yaml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
This file is autogenerated, but we've stopped checking such files into the
|
||||||
|
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
|
||||||
|
populate this file.
|
@ -4663,6 +4663,8 @@ runTests() {
|
|||||||
# Cluster Role #
|
# Cluster Role #
|
||||||
################
|
################
|
||||||
|
|
||||||
|
kubectl "${kube_flags[@]}" api-resources
|
||||||
|
|
||||||
if kube::test::if_supports_resource "${clusterroles}" ; then
|
if kube::test::if_supports_resource "${clusterroles}" ; then
|
||||||
record_command run_clusterroles_tests
|
record_command run_clusterroles_tests
|
||||||
fi
|
fi
|
||||||
|
@ -9,6 +9,7 @@ go_library(
|
|||||||
srcs = [
|
srcs = [
|
||||||
"alpha.go",
|
"alpha.go",
|
||||||
"annotate.go",
|
"annotate.go",
|
||||||
|
"apiresources.go",
|
||||||
"apiversions.go",
|
"apiversions.go",
|
||||||
"apply.go",
|
"apply.go",
|
||||||
"apply_edit_last_applied.go",
|
"apply_edit_last_applied.go",
|
||||||
|
214
pkg/kubectl/cmd/apiresources.go
Normal file
214
pkg/kubectl/cmd/apiresources.go
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
apiresources_example = templates.Examples(`
|
||||||
|
# Print the supported API Resources
|
||||||
|
kubectl api-resources
|
||||||
|
|
||||||
|
# Print the supported API Resources with more information
|
||||||
|
kubectl api-resources -o wide
|
||||||
|
|
||||||
|
# Print the supported namespaced resources
|
||||||
|
kubectl api-resources --namespaced=true
|
||||||
|
|
||||||
|
# Print the supported non-namespaced resources
|
||||||
|
kubectl api-resources --namespaced=false
|
||||||
|
|
||||||
|
# Print the supported API Resources with specific APIGroup
|
||||||
|
kubectl api-resources --api-group=extensions`)
|
||||||
|
)
|
||||||
|
|
||||||
|
// ApiResourcesOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of
|
||||||
|
// referencing the cmd.Flags()
|
||||||
|
type ApiResourcesOptions struct {
|
||||||
|
out io.Writer
|
||||||
|
|
||||||
|
Output string
|
||||||
|
APIGroup string
|
||||||
|
Namespaced bool
|
||||||
|
NoHeaders bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// groupResource contains the APIGroup and APIResource
|
||||||
|
type groupResource struct {
|
||||||
|
APIGroup string
|
||||||
|
APIResource metav1.APIResource
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCmdApiResources(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
|
options := &ApiResourcesOptions{
|
||||||
|
out: out,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "api-resources",
|
||||||
|
Short: "Print the supported API resources on the server",
|
||||||
|
Long: "Print the supported API resources on the server",
|
||||||
|
Example: apiresources_example,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
cmdutil.CheckErr(options.Complete(cmd))
|
||||||
|
cmdutil.CheckErr(options.Validate(cmd))
|
||||||
|
cmdutil.CheckErr(options.RunApiResources(cmd, f))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cmdutil.AddOutputFlags(cmd)
|
||||||
|
cmdutil.AddNoHeadersFlags(cmd)
|
||||||
|
cmd.Flags().StringVar(&options.APIGroup, "api-group", "", "The API group to use when talking to the server.")
|
||||||
|
cmd.Flags().BoolVar(&options.Namespaced, "namespaced", true, "Namespaced indicates if a resource is namespaced or not.")
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *ApiResourcesOptions) Complete(cmd *cobra.Command) error {
|
||||||
|
o.Output = cmdutil.GetFlagString(cmd, "output")
|
||||||
|
o.NoHeaders = cmdutil.GetFlagBool(cmd, "no-headers")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *ApiResourcesOptions) Validate(cmd *cobra.Command) error {
|
||||||
|
validOutputTypes := sets.NewString("", "json", "yaml", "wide", "name", "custom-columns", "custom-columns-file", "go-template", "go-template-file", "jsonpath", "jsonpath-file")
|
||||||
|
supportedOutputTypes := sets.NewString("", "wide")
|
||||||
|
outputFormat := cmdutil.GetFlagString(cmd, "output")
|
||||||
|
if !validOutputTypes.Has(outputFormat) {
|
||||||
|
return fmt.Errorf("output must be one of '' or 'wide': %v", outputFormat)
|
||||||
|
}
|
||||||
|
if !supportedOutputTypes.Has(outputFormat) {
|
||||||
|
return fmt.Errorf("--output %v is not available in kubectl api-resources", outputFormat)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *ApiResourcesOptions) RunApiResources(cmd *cobra.Command, f cmdutil.Factory) error {
|
||||||
|
w := printers.GetNewTabWriter(o.out)
|
||||||
|
defer w.Flush()
|
||||||
|
|
||||||
|
discoveryclient, err := f.DiscoveryClient()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always request fresh data from the server
|
||||||
|
discoveryclient.Invalidate()
|
||||||
|
|
||||||
|
lists, err := discoveryclient.ServerPreferredResources()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
resources := []groupResource{}
|
||||||
|
|
||||||
|
groupChanged := cmd.Flags().Changed("api-group")
|
||||||
|
nsChanged := cmd.Flags().Changed("namespaced")
|
||||||
|
|
||||||
|
for _, list := range lists {
|
||||||
|
if len(list.APIResources) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
gv, err := schema.ParseGroupVersion(list.GroupVersion)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, resource := range list.APIResources {
|
||||||
|
if len(resource.Verbs) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// filter apiGroup
|
||||||
|
if groupChanged && o.APIGroup != gv.Group {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// filter namespaced
|
||||||
|
if nsChanged && o.Namespaced != resource.Namespaced {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
resources = append(resources, groupResource{
|
||||||
|
APIGroup: gv.Group,
|
||||||
|
APIResource: resource,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if o.NoHeaders == false {
|
||||||
|
if err = printContextHeaders(w, o.Output); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Stable(sortableGroupResource(resources))
|
||||||
|
for _, r := range resources {
|
||||||
|
if o.Output == "wide" {
|
||||||
|
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%v\t%s\t%v\n",
|
||||||
|
r.APIResource.Name,
|
||||||
|
strings.Join(r.APIResource.ShortNames, ","),
|
||||||
|
r.APIGroup,
|
||||||
|
r.APIResource.Namespaced,
|
||||||
|
r.APIResource.Kind,
|
||||||
|
r.APIResource.Verbs); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%v\t%s\n",
|
||||||
|
r.APIResource.Name,
|
||||||
|
strings.Join(r.APIResource.ShortNames, ","),
|
||||||
|
r.APIGroup,
|
||||||
|
r.APIResource.Namespaced,
|
||||||
|
r.APIResource.Kind); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func printContextHeaders(out io.Writer, output string) error {
|
||||||
|
columnNames := []string{"NAME", "SHORTNAMES", "APIGROUP", "NAMESPACED", "KIND"}
|
||||||
|
if output == "wide" {
|
||||||
|
columnNames = append(columnNames, "VERBS")
|
||||||
|
}
|
||||||
|
_, err := fmt.Fprintf(out, "%s\n", strings.Join(columnNames, "\t"))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type sortableGroupResource []groupResource
|
||||||
|
|
||||||
|
func (s sortableGroupResource) Len() int { return len(s) }
|
||||||
|
func (s sortableGroupResource) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||||
|
func (s sortableGroupResource) Less(i, j int) bool {
|
||||||
|
ret := strings.Compare(s[i].APIGroup, s[j].APIGroup)
|
||||||
|
if ret > 0 {
|
||||||
|
return false
|
||||||
|
} else if ret == 0 {
|
||||||
|
return strings.Compare(s[i].APIResource.Name, s[j].APIResource.Name) < 0
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
@ -346,6 +346,7 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
|
|||||||
cmds.AddCommand(NewCmdPlugin(f, in, out, err))
|
cmds.AddCommand(NewCmdPlugin(f, in, out, err))
|
||||||
cmds.AddCommand(NewCmdVersion(f, out))
|
cmds.AddCommand(NewCmdVersion(f, out))
|
||||||
cmds.AddCommand(NewCmdApiVersions(f, out))
|
cmds.AddCommand(NewCmdApiVersions(f, out))
|
||||||
|
cmds.AddCommand(NewCmdApiResources(f, out))
|
||||||
cmds.AddCommand(NewCmdOptions(out))
|
cmds.AddCommand(NewCmdOptions(out))
|
||||||
|
|
||||||
return cmds
|
return cmds
|
||||||
|
Loading…
Reference in New Issue
Block a user