Skip to content

Commit

Permalink
Merge pull request #42873 from xilabao/add-apiresources-command
Browse files Browse the repository at this point in the history
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

add kubectl api-resources command

**What this PR does / why we need it**:
As the RBAC role need to be related to resources. I think we can use the command to get the supported resources. 

```
# ./cluster/kubectl.sh api-resources   
NAME                                  SHORTNAMES   APIGROUP                       NAMESPACED   KIND
bindings                                                                          true         Binding
componentstatuses                     cs                                          false        ComponentStatus
configmaps                            cm                                          true         ConfigMap
endpoints                             ep                                          true         Endpoints
events                                ev                                          true         Event
limitranges                           limits                                      true         LimitRange
namespaces                            ns                                          false        Namespace
nodes                                 no                                          false        Node
persistentvolumeclaims                pvc                                         true         PersistentVolumeClaim
persistentvolumes                     pv                                          false        PersistentVolume
pods                                  po                                          true         Pod
podtemplates                                                                      true         PodTemplate
replicationcontrollers                rc                                          true         ReplicationController
resourcequotas                        quota                                       true         ResourceQuota
secrets                                                                           true         Secret
serviceaccounts                       sa                                          true         ServiceAccount
services                              svc                                         true         Service
externaladmissionhookconfigurations                admissionregistration.k8s.io   false        ExternalAdmissionHookConfiguration
initializerconfigurations                          admissionregistration.k8s.io   false        InitializerConfiguration
customresourcedefinitions             crd          apiextensions.k8s.io           false        CustomResourceDefinition
apiservices                                        apiregistration.k8s.io         false        APIService
controllerrevisions                                apps                           true         ControllerRevision
daemonsets                            ds           apps                           true         DaemonSet
deployments                           deploy       apps                           true         Deployment
replicasets                           rs           apps                           true         ReplicaSet
statefulsets                          sts          apps                           true         StatefulSet
tokenreviews                                       authentication.k8s.io          false        TokenReview
localsubjectaccessreviews                          authorization.k8s.io           true         LocalSubjectAccessReview
selfsubjectaccessreviews                           authorization.k8s.io           false        SelfSubjectAccessReview
subjectaccessreviews                               authorization.k8s.io           false        SubjectAccessReview
horizontalpodautoscalers              hpa          autoscaling                    true         HorizontalPodAutoscaler
jobs                                               batch                          true         Job
certificatesigningrequests            csr          certificates.k8s.io            false        CertificateSigningRequest
daemonsets                            ds           extensions                     true         DaemonSet
deployments                           deploy       extensions                     true         Deployment
ingresses                             ing          extensions                     true         Ingress
networkpolicies                       netpol       extensions                     true         NetworkPolicy
podsecuritypolicies                   psp          extensions                     false        PodSecurityPolicy
replicasets                           rs           extensions                     true         ReplicaSet
networkpolicies                       netpol       networking.k8s.io              true         NetworkPolicy
poddisruptionbudgets                  pdb          policy                         true         PodDisruptionBudget
clusterrolebindings                                rbac.authorization.k8s.io      false        ClusterRoleBinding
clusterroles                                       rbac.authorization.k8s.io      false        ClusterRole
rolebindings                                       rbac.authorization.k8s.io      true         RoleBinding
roles                                              rbac.authorization.k8s.io      true         Role
podpresets                                         settings.k8s.io                true         PodPreset
storageclasses                        sc           storage.k8s.io                 false        StorageClass
```
**Which issue this PR fixes**: fixes #42932

**Special notes for your reviewer**:

**Release note**:

```release-note
add kubectl api-resources command to discovery of resources
```
  • Loading branch information
Kubernetes Submit Queue committed Apr 3, 2018
2 parents 9c40f5b + 110641b commit 229d2df
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 0 deletions.
3 changes: 3 additions & 0 deletions docs/.generated_docs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ docs/man/man1/kubeadm.1
docs/man/man1/kubectl-alpha-diff.1
docs/man/man1/kubectl-alpha.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-apply-edit-last-applied.1
docs/man/man1/kubectl-apply-set-last-applied.1
Expand Down Expand Up @@ -245,6 +246,7 @@ docs/user-guide/kubectl/kubectl.md
docs/user-guide/kubectl/kubectl_alpha.md
docs/user-guide/kubectl/kubectl_alpha_diff.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_apply.md
docs/user-guide/kubectl/kubectl_apply_edit-last-applied.md
Expand Down Expand Up @@ -341,6 +343,7 @@ docs/user-guide/kubectl/kubectl_version.md
docs/yaml/kubectl/kubectl.yaml
docs/yaml/kubectl/kubectl_alpha.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_apply.yaml
docs/yaml/kubectl/kubectl_attach.yaml
Expand Down
3 changes: 3 additions & 0 deletions docs/man/man1/kubectl-api-resources.1
Original file line number Diff line number Diff line change
@@ -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 changes: 3 additions & 0 deletions docs/user-guide/kubectl/kubectl_api-resources.md
Original file line number Diff line number Diff line change
@@ -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 changes: 3 additions & 0 deletions docs/yaml/kubectl/kubectl_api-resources.yaml
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 2 additions & 0 deletions hack/make-rules/test-cmd-util.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4884,6 +4884,8 @@ runTests() {
# Cluster Role #
################

kubectl "${kube_flags[@]}" api-resources

if kube::test::if_supports_resource "${clusterroles}" ; then
record_command run_clusterroles_tests
fi
Expand Down
1 change: 1 addition & 0 deletions pkg/kubectl/cmd/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ go_library(
srcs = [
"alpha.go",
"annotate.go",
"apiresources.go",
"apiversions.go",
"apply.go",
"apply_edit_last_applied.go",
Expand Down
214 changes: 214 additions & 0 deletions pkg/kubectl/cmd/apiresources.go
Original file line number Diff line number Diff line change
@@ -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
}
1 change: 1 addition & 0 deletions pkg/kubectl/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(NewCmdVersion(f, out))
cmds.AddCommand(NewCmdApiVersions(f, out))
cmds.AddCommand(NewCmdApiResources(f, out))
cmds.AddCommand(NewCmdOptions(out))

return cmds
Expand Down

0 comments on commit 229d2df

Please sign in to comment.