From d604639752a75ffb800df1909cc6a0285e813a6b Mon Sep 17 00:00:00 2001 From: Shiming Zhang Date: Wed, 28 Aug 2024 19:21:04 +0800 Subject: [PATCH] [augerctl] Support shortname and check namespace for built-in resource Signed-off-by: Shiming Zhang --- Makefile | 17 +- augerctl/README.md | 4 +- augerctl/command/get_command.go | 20 +- go.mod | 16 + go.sum | 49 +++ hack/gen_wellknown_resources/main.go | 138 +++++++ pkg/wellknown/resources.go | 519 +++++++++++++++++++++++++++ pkg/wellknown/utils.go | 53 +++ pkg/wellknown/utils_test.go | 143 ++++++++ 9 files changed, 953 insertions(+), 6 deletions(-) create mode 100644 hack/gen_wellknown_resources/main.go create mode 100644 pkg/wellknown/resources.go create mode 100644 pkg/wellknown/utils.go create mode 100644 pkg/wellknown/utils_test.go diff --git a/Makefile b/Makefile index 45814a1..60103a7 100644 --- a/Makefile +++ b/Makefile @@ -74,7 +74,22 @@ pkg/scheme/scheme.go: ./hack/gen_scheme.sh go.mod -rm ./pkg/scheme/scheme.go ./hack/gen_scheme.sh > ./pkg/scheme/scheme.go +pkg/wellknown/resources.go: ./hack/gen_wellknown_resources + KWOK_KUBE_VERSION=1.31.0 kwokctl create cluster --name auger-wellknown \ + --kube-apiserver-insecure-port 8080 \ + --runtime binary \ + --disable-kube-controller-manager \ + --disable-kube-scheduler \ + --kubeconfig ./auger-wellknown.kubeconfig + -rm pkg/wellknown/resources.go + go run ./hack/gen_wellknown_resources ./auger-wellknown.kubeconfig > pkg/wellknown/resources.go + kwokctl delete cluster --name auger-wellknown \ + --kubeconfig ./auger-wellknown.kubeconfig + rm ./auger-wellknown.kubeconfig + .PHONY: generate -generate: pkg/scheme/scheme.go +generate: \ + pkg/scheme/scheme.go \ + pkg/wellknown/resources.go .PHONY: build test release release-docker-build clean diff --git a/augerctl/README.md b/augerctl/README.md index 9e8ea2b..6a55647 100644 --- a/augerctl/README.md +++ b/augerctl/README.md @@ -62,10 +62,10 @@ TODO List a single service with namespace `default` and name `kubernetes` ``` bash -augerctl get services -n default kubernetes +augerctl get svc -n default kubernetes # Nearly equivalent -kubectl get services -n default kubernetes -o yaml +kubectl get svc -n default kubernetes -o yaml ``` List a single resource of type `priorityclasses` and name `system-node-critical` without namespaced diff --git a/augerctl/command/get_command.go b/augerctl/command/get_command.go index 8ce1aba..a6640f2 100644 --- a/augerctl/command/get_command.go +++ b/augerctl/command/get_command.go @@ -22,6 +22,7 @@ import ( "os" "github.com/etcd-io/auger/pkg/client" + "github.com/etcd-io/auger/pkg/wellknown" "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/runtime/schema" ) @@ -31,14 +32,16 @@ type getFlagpole struct { Output string ChunkSize int64 Prefix string + + AllNamespace bool } var ( getExample = ` # List a single service with namespace "default" and name "kubernetes" - augerctl get services -n default kubernetes + augerctl get svc -n default kubernetes # Nearly equivalent - kubectl get services -n default kubernetes -o yaml + kubectl get svc -n default kubernetes -o yaml # List a single resource of type "priorityclasses" and name "system-node-critical" without namespaced augerctl get priorityclasses system-node-critical @@ -88,6 +91,7 @@ func newCtlGetCommand(f *flagpole) *cobra.Command { cmd.Flags().StringVarP(&flags.Namespace, "namespace", "n", "", "namespace of resource") cmd.Flags().Int64Var(&flags.ChunkSize, "chunk-size", 500, "chunk size of the list pager") cmd.Flags().StringVar(&flags.Prefix, "prefix", "/registry", "prefix to prepend to the resource") + cmd.Flags().BoolVarP(&flags.AllNamespace, "all-namespace", "A", false, "if present, list the requested object(s) across all namespaces") return cmd } @@ -97,7 +101,7 @@ func getCommand(ctx context.Context, etcdclient client.Client, flags *getFlagpol var targetName string var targetNamespace string if len(args) != 0 { - // TODO: Support get information from CRD and scheme.Codecs + // TODO: Support get information from CRD // Support short name // Check for namespaced @@ -110,6 +114,16 @@ func getCommand(ctx context.Context, etcdclient client.Client, flags *getFlagpol if len(args) >= 2 { targetName = args[1] } + + if correctGr, namespaced, found := wellknown.CorrectGroupResource(gr); found { + targetGr = correctGr + if !namespaced || flags.AllNamespace { + targetNamespace = "" + } else if flags.Namespace == "" { + targetNamespace = "default" + } + } + } printer := NewPrinter(os.Stdout, flags.Output) diff --git a/go.mod b/go.mod index ae522d0..50779dd 100644 --- a/go.mod +++ b/go.mod @@ -20,22 +20,37 @@ require ( require ( github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-logr/logr v1.4.2 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/imdario/mergo v0.3.6 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/x448/float16 v0.8.4 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/net v0.28.0 // indirect + golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/sys v0.24.0 // indirect + golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.17.0 // indirect + golang.org/x/time v0.3.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect google.golang.org/grpc v1.65.0 // indirect @@ -43,6 +58,7 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect diff --git a/go.sum b/go.sum index d656198..5c52b06 100644 --- a/go.sum +++ b/go.sum @@ -3,42 +3,75 @@ github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03V github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/safetext v0.0.0-20220914124124-e18e3fe012bf h1:F57w3YBUKQis5sQo3d8O6JhlvF4/p3zRfRtpIfSnBu4= github.com/google/safetext v0.0.0-20220914124124-e18e3fe012bf/go.mod h1:Tv1PlzqC9t8wNnpPdctvtSUOPUUg4SHeE6vR1Ir2hmg= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -50,7 +83,12 @@ github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3k github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -82,6 +120,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -92,14 +132,20 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -120,6 +166,7 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo= @@ -130,6 +177,8 @@ k8s.io/client-go v0.31.0 h1:QqEJzNjbN2Yv1H79SsS+SWnXkBgVu4Pj3CJQgbx0gI8= k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= diff --git a/hack/gen_wellknown_resources/main.go b/hack/gen_wellknown_resources/main.go new file mode 100644 index 0000000..0b2a3e6 --- /dev/null +++ b/hack/gen_wellknown_resources/main.go @@ -0,0 +1,138 @@ +/* +Copyright 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 main + +import ( + "fmt" + "go/format" + "os" + "sort" + "strings" + + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" +) + +func main() { + err := gen() + if err != nil { + panic(err) + } +} + +func gen() error { + clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( + &clientcmd.ClientConfigLoadingRules{ExplicitPath: os.Args[1]}, + &clientcmd.ConfigOverrides{}) + + restConfig, err := clientConfig.ClientConfig() + if err != nil { + return err + } + + clientset, err := kubernetes.NewForConfig(restConfig) + if err != nil { + return err + } + + resourceList, err := clientset.Discovery().ServerPreferredResources() + if err != nil { + return err + } + + var wellKnown []resource + + for _, list := range resourceList { + gv, err := schema.ParseGroupVersion(list.GroupVersion) + if err != nil { + return err + } + for _, ar := range list.APIResources { + + names := []string{ar.Name} + if ar.SingularName != ar.Name { + names = append(names, ar.SingularName) + } + names = append(names, ar.ShortNames...) + + wellKnown = append(wellKnown, resource{ + Names: names, + Namespaced: ar.Namespaced, + Group: gv.Group, + }) + } + } + + sort.Slice(wellKnown, func(i, j int) bool { + if wellKnown[i].Group == wellKnown[j].Group { + return wellKnown[i].Names[0] < wellKnown[j].Names[0] + } + return wellKnown[i].Group < wellKnown[j].Group + }) + + out := fmt.Sprintf("%#v", wellKnown) + out = strings.ReplaceAll(out, "[]main.resource{", "[]resource{\n") + out = strings.ReplaceAll(out, "main.resource{", "{\n") + out = strings.ReplaceAll(out, " ", "\n") + out = strings.ReplaceAll(out, "\"}", "\",\n}") + out = strings.ReplaceAll(out, "{\"", "{\n\"") + out = strings.ReplaceAll(out, "}}", "},\n}") + + out = ` +/* +Copyright 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 wellknown + +type resource struct { + Names []string + Namespaced bool + Group string +} + +// Don't edit this file directly. It is generated by hack/gen_wellknown_resources +var resources = ` + out + + formated, err := format.Source([]byte(out)) + if err != nil { + return err + } + out = strings.TrimSpace(string(formated)) + fmt.Println(out) + + return nil +} + +type resource struct { + Names []string + Namespaced bool + Group string +} diff --git a/pkg/wellknown/resources.go b/pkg/wellknown/resources.go new file mode 100644 index 0000000..de5878f --- /dev/null +++ b/pkg/wellknown/resources.go @@ -0,0 +1,519 @@ +/* +Copyright 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 wellknown + +type resource struct { + Names []string + Namespaced bool + Group string +} + +// Don't edit this file directly. It is generated by hack/gen_wellknown_resources +var resources = []resource{ + { + Names: []string{ + "bindings", + "binding", + }, + Namespaced: true, + Group: "", + }, + { + Names: []string{ + "componentstatuses", + "componentstatus", + "cs", + }, + Namespaced: false, + Group: "", + }, + { + Names: []string{ + "configmaps", + "configmap", + "cm", + }, + Namespaced: true, + Group: "", + }, + { + Names: []string{ + "endpoints", + "ep", + }, + Namespaced: true, + Group: "", + }, + { + Names: []string{ + "events", + "event", + "ev", + }, + Namespaced: true, + Group: "", + }, + { + Names: []string{ + "limitranges", + "limitrange", + "limits", + }, + Namespaced: true, + Group: "", + }, + { + Names: []string{ + "namespaces", + "namespace", + "ns", + }, + Namespaced: false, + Group: "", + }, + { + Names: []string{ + "nodes", + "node", + "no", + }, + Namespaced: false, + Group: "", + }, + { + Names: []string{ + "persistentvolumeclaims", + "persistentvolumeclaim", + "pvc", + }, + Namespaced: true, + Group: "", + }, + { + Names: []string{ + "persistentvolumes", + "persistentvolume", + "pv", + }, + Namespaced: false, + Group: "", + }, + { + Names: []string{ + "pods", + "pod", + "po", + }, + Namespaced: true, + Group: "", + }, + { + Names: []string{ + "podtemplates", + "podtemplate", + }, + Namespaced: true, + Group: "", + }, + { + Names: []string{ + "replicationcontrollers", + "replicationcontroller", + "rc", + }, + Namespaced: true, + Group: "", + }, + { + Names: []string{ + "resourcequotas", + "resourcequota", + "quota", + }, + Namespaced: true, + Group: "", + }, + { + Names: []string{ + "secrets", + "secret", + }, + Namespaced: true, + Group: "", + }, + { + Names: []string{ + "serviceaccounts", + "serviceaccount", + "sa", + }, + Namespaced: true, + Group: "", + }, + { + Names: []string{ + "services", + "service", + "svc", + }, + Namespaced: true, + Group: "", + }, + { + Names: []string{ + "mutatingwebhookconfigurations", + "mutatingwebhookconfiguration", + }, + Namespaced: false, + Group: "admissionregistration.k8s.io", + }, + { + Names: []string{ + "validatingadmissionpolicies", + "validatingadmissionpolicy", + }, + Namespaced: false, + Group: "admissionregistration.k8s.io", + }, + { + Names: []string{ + "validatingadmissionpolicybindings", + "validatingadmissionpolicybinding", + }, + Namespaced: false, + Group: "admissionregistration.k8s.io", + }, + { + Names: []string{ + "validatingwebhookconfigurations", + "validatingwebhookconfiguration", + }, + Namespaced: false, + Group: "admissionregistration.k8s.io", + }, + { + Names: []string{ + "customresourcedefinitions", + "customresourcedefinition", + "crd", + "crds", + }, + Namespaced: false, + Group: "apiextensions.k8s.io", + }, + { + Names: []string{ + "apiservices", + "apiservice", + }, + Namespaced: false, + Group: "apiregistration.k8s.io", + }, + { + Names: []string{ + "controllerrevisions", + "controllerrevision", + }, + Namespaced: true, + Group: "apps", + }, + { + Names: []string{ + "daemonsets", + "daemonset", + "ds", + }, + Namespaced: true, + Group: "apps", + }, + { + Names: []string{ + "deployments", + "deployment", + "deploy", + }, + Namespaced: true, + Group: "apps", + }, + { + Names: []string{ + "replicasets", + "replicaset", + "rs", + }, + Namespaced: true, + Group: "apps", + }, + { + Names: []string{ + "statefulsets", + "statefulset", + "sts", + }, + Namespaced: true, + Group: "apps", + }, + { + Names: []string{ + "selfsubjectreviews", + "selfsubjectreview", + }, + Namespaced: false, + Group: "authentication.k8s.io", + }, + { + Names: []string{ + "tokenreviews", + "tokenreview", + }, + Namespaced: false, + Group: "authentication.k8s.io", + }, + { + Names: []string{ + "localsubjectaccessreviews", + "localsubjectaccessreview", + }, + Namespaced: true, + Group: "authorization.k8s.io", + }, + { + Names: []string{ + "selfsubjectaccessreviews", + "selfsubjectaccessreview", + }, + Namespaced: false, + Group: "authorization.k8s.io", + }, + { + Names: []string{ + "selfsubjectrulesreviews", + "selfsubjectrulesreview", + }, + Namespaced: false, + Group: "authorization.k8s.io", + }, + { + Names: []string{ + "subjectaccessreviews", + "subjectaccessreview", + }, + Namespaced: false, + Group: "authorization.k8s.io", + }, + { + Names: []string{ + "horizontalpodautoscalers", + "horizontalpodautoscaler", + "hpa", + }, + Namespaced: true, + Group: "autoscaling", + }, + { + Names: []string{ + "cronjobs", + "cronjob", + "cj", + }, + Namespaced: true, + Group: "batch", + }, + { + Names: []string{ + "jobs", + "job", + }, + Namespaced: true, + Group: "batch", + }, + { + Names: []string{ + "certificatesigningrequests", + "certificatesigningrequest", + "csr", + }, + Namespaced: false, + Group: "certificates.k8s.io", + }, + { + Names: []string{ + "leases", + "lease", + }, + Namespaced: true, + Group: "coordination.k8s.io", + }, + { + Names: []string{ + "endpointslices", + "endpointslice", + }, + Namespaced: true, + Group: "discovery.k8s.io", + }, + { + Names: []string{ + "events", + "event", + "ev", + }, + Namespaced: true, + Group: "events.k8s.io", + }, + { + Names: []string{ + "flowschemas", + "flowschema", + }, + Namespaced: false, + Group: "flowcontrol.apiserver.k8s.io", + }, + { + Names: []string{ + "prioritylevelconfigurations", + "prioritylevelconfiguration", + }, + Namespaced: false, + Group: "flowcontrol.apiserver.k8s.io", + }, + { + Names: []string{ + "ingressclasses", + "ingressclass", + }, + Namespaced: false, + Group: "networking.k8s.io", + }, + { + Names: []string{ + "ingresses", + "ingress", + "ing", + }, + Namespaced: true, + Group: "networking.k8s.io", + }, + { + Names: []string{ + "networkpolicies", + "networkpolicy", + "netpol", + }, + Namespaced: true, + Group: "networking.k8s.io", + }, + { + Names: []string{ + "runtimeclasses", + "runtimeclass", + }, + Namespaced: false, + Group: "node.k8s.io", + }, + { + Names: []string{ + "poddisruptionbudgets", + "poddisruptionbudget", + "pdb", + }, + Namespaced: true, + Group: "policy", + }, + { + Names: []string{ + "clusterrolebindings", + "clusterrolebinding", + }, + Namespaced: false, + Group: "rbac.authorization.k8s.io", + }, + { + Names: []string{ + "clusterroles", + "clusterrole", + }, + Namespaced: false, + Group: "rbac.authorization.k8s.io", + }, + { + Names: []string{ + "rolebindings", + "rolebinding", + }, + Namespaced: true, + Group: "rbac.authorization.k8s.io", + }, + { + Names: []string{ + "roles", + "role", + }, + Namespaced: true, + Group: "rbac.authorization.k8s.io", + }, + { + Names: []string{ + "priorityclasses", + "priorityclass", + "pc", + }, + Namespaced: false, + Group: "scheduling.k8s.io", + }, + { + Names: []string{ + "csidrivers", + "csidriver", + }, + Namespaced: false, + Group: "storage.k8s.io", + }, + { + Names: []string{ + "csinodes", + "csinode", + }, + Namespaced: false, + Group: "storage.k8s.io", + }, + { + Names: []string{ + "csistoragecapacities", + "csistoragecapacity", + }, + Namespaced: true, + Group: "storage.k8s.io", + }, + { + Names: []string{ + "storageclasses", + "storageclass", + "sc", + }, + Namespaced: false, + Group: "storage.k8s.io", + }, + { + Names: []string{ + "volumeattachments", + "volumeattachment", + }, + Namespaced: false, + Group: "storage.k8s.io", + }, +} diff --git a/pkg/wellknown/utils.go b/pkg/wellknown/utils.go new file mode 100644 index 0000000..3e2b606 --- /dev/null +++ b/pkg/wellknown/utils.go @@ -0,0 +1,53 @@ +/* +Copyright 2024 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 wellknown + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + nameToResource = map[string]*resource{} + nameAndGroupToResource = map[schema.GroupResource]*resource{} +) + +func init() { + for i, r := range resources { + for _, name := range r.Names { + nameToResource[name] = &resources[i] + nameAndGroupToResource[schema.GroupResource{Resource: name, Group: r.Group}] = &resources[i] + } + } +} + +// CorrectGroupResource returns the corrected GroupResource and namespaced +func CorrectGroupResource(target schema.GroupResource) (gr schema.GroupResource, namespaced bool, found bool) { + var r *resource + if target.Group == "" { + r, found = nameToResource[target.Resource] + } else { + r, found = nameAndGroupToResource[target] + } + if !found { + return gr, namespaced, false + } + gr = schema.GroupResource{ + Group: r.Group, + Resource: r.Names[0], + } + return gr, r.Namespaced, true +} diff --git a/pkg/wellknown/utils_test.go b/pkg/wellknown/utils_test.go new file mode 100644 index 0000000..d92c96f --- /dev/null +++ b/pkg/wellknown/utils_test.go @@ -0,0 +1,143 @@ +/* +Copyright 2024 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 wellknown + +import ( + "reflect" + "testing" + + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func TestCorrectGroupResource(t *testing.T) { + type args struct { + target schema.GroupResource + } + tests := []struct { + name string + args args + wantGr schema.GroupResource + wantNamespaced bool + wantFound bool + }{ + { + name: "empty", + args: args{ + target: schema.GroupResource{ + Resource: "", + }, + }, + wantFound: false, + }, + { + name: "pods", + args: args{ + target: schema.GroupResource{ + Resource: "pods", + }, + }, + wantGr: schema.GroupResource{ + Resource: "pods", + }, + wantNamespaced: true, + wantFound: true, + }, + { + name: "pod", + args: args{ + target: schema.GroupResource{ + Resource: "pod", + }, + }, + wantGr: schema.GroupResource{ + Resource: "pods", + }, + wantNamespaced: true, + wantFound: true, + }, + { + name: "po", + args: args{ + target: schema.GroupResource{ + Resource: "po", + }, + }, + wantGr: schema.GroupResource{ + Resource: "pods", + }, + wantNamespaced: true, + wantFound: true, + }, + { + name: "role", + args: args{ + target: schema.GroupResource{ + Resource: "role", + }, + }, + wantGr: schema.GroupResource{ + Resource: "roles", + Group: "rbac.authorization.k8s.io", + }, + wantNamespaced: true, + wantFound: true, + }, + { + name: "no", + args: args{ + target: schema.GroupResource{ + Resource: "no", + }, + }, + wantGr: schema.GroupResource{ + Resource: "nodes", + Group: "", + }, + wantNamespaced: false, + wantFound: true, + }, + { + name: "deploy.apps", + args: args{ + target: schema.GroupResource{ + Resource: "deploy", + Group: "apps", + }, + }, + wantGr: schema.GroupResource{ + Resource: "deployments", + Group: "apps", + }, + wantNamespaced: true, + wantFound: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotGr, gotNamespaced, gotFound := CorrectGroupResource(tt.args.target) + if !reflect.DeepEqual(gotGr, tt.wantGr) { + t.Errorf("CorrectGroupResource() gotGr = %v, want %v", gotGr, tt.wantGr) + } + if gotNamespaced != tt.wantNamespaced { + t.Errorf("CorrectGroupResource() gotNamespaced = %v, want %v", gotNamespaced, tt.wantNamespaced) + } + if gotFound != tt.wantFound { + t.Errorf("CorrectGroupResource() gotFound = %v, want %v", gotFound, tt.wantFound) + } + }) + } +}