Merge pull request #54446 from smarterclayton/cleanup_get

Automatic merge from submit-queue (batch tested with PRs 54446, 54202). 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>.

Create a new package for generic commands like get

This is in preparation for cleaning up the structure of `kubectl get` to ease implementing serverside get and streaming API responses. Moves a hardcoded constant into a method in preparation for a future serverside implementation. Also improves some existing description text.
pull/6/head
Kubernetes Submit Queue 2017-10-31 15:51:23 -07:00 committed by GitHub
commit 037b8ab8b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 305 additions and 97 deletions

View File

@ -174,6 +174,7 @@ package_group(
"//pkg/kubectl/cmd",
"//pkg/kubectl/cmd/auth",
"//pkg/kubectl/cmd/config",
"//pkg/kubectl/cmd/resource",
"//pkg/kubectl/cmd/rollout",
"//pkg/kubectl/cmd/set",
"//pkg/kubectl/cmd/templates",
@ -194,6 +195,7 @@ package_group(
packages = [
"//pkg/kubectl/cmd",
"//pkg/kubectl/cmd/auth",
"//pkg/kubectl/cmd/resource",
"//pkg/kubectl/cmd/set",
],
)
@ -223,6 +225,7 @@ package_group(
"//pkg/kubectl/cmd",
"//pkg/kubectl/cmd/auth",
"//pkg/kubectl/cmd/config",
"//pkg/kubectl/cmd/resource",
"//pkg/kubectl/cmd/rollout",
"//pkg/kubectl/cmd/set",
"//pkg/kubectl/cmd/testing",
@ -290,6 +293,7 @@ package_group(
"//pkg/kubectl/cmd",
"//pkg/kubectl/cmd/auth",
"//pkg/kubectl/cmd/config",
"//pkg/kubectl/cmd/resource",
"//pkg/kubectl/cmd/rollout",
"//pkg/kubectl/cmd/set",
"//pkg/kubectl/cmd/testing",

View File

@ -44,7 +44,6 @@ go_library(
"exec.go",
"explain.go",
"expose.go",
"get.go",
"help.go",
"label.go",
"logs.go",
@ -80,12 +79,12 @@ go_library(
"//pkg/kubectl/apply/strategy:go_default_library",
"//pkg/kubectl/cmd/auth:go_default_library",
"//pkg/kubectl/cmd/config:go_default_library",
"//pkg/kubectl/cmd/resource:go_default_library",
"//pkg/kubectl/cmd/rollout:go_default_library",
"//pkg/kubectl/cmd/set:go_default_library",
"//pkg/kubectl/cmd/templates:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/cmd/util/editor:go_default_library",
"//pkg/kubectl/cmd/util/openapi:go_default_library",
"//pkg/kubectl/explain:go_default_library",
"//pkg/kubectl/metricsutil:go_default_library",
"//pkg/kubectl/plugins:go_default_library",
@ -179,7 +178,6 @@ go_test(
"edit_test.go",
"exec_test.go",
"expose_test.go",
"get_test.go",
"label_test.go",
"logs_test.go",
"patch_test.go",
@ -206,13 +204,11 @@ go_test(
"//pkg/api/ref:go_default_library",
"//pkg/api/testapi:go_default_library",
"//pkg/api/testing:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apis/batch:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/kubectl:go_default_library",
"//pkg/kubectl/cmd/testing:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/cmd/util/openapi:go_default_library",
"//pkg/kubectl/plugins:go_default_library",
"//pkg/kubectl/resource:go_default_library",
"//pkg/kubectl/scheme:go_default_library",
@ -228,7 +224,6 @@ go_test(
"//vendor/k8s.io/api/policy/v1beta1:go_default_library",
"//vendor/k8s.io/api/rbac/v1:go_default_library",
"//vendor/k8s.io/api/rbac/v1beta1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
@ -236,21 +231,16 @@ go_test(
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/client-go/dynamic:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/rest/fake:go_default_library",
"//vendor/k8s.io/client-go/rest/watch:go_default_library",
"//vendor/k8s.io/client-go/tools/remotecommand:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
"//vendor/k8s.io/metrics/pkg/apis/metrics/v1alpha1:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
],
@ -268,6 +258,7 @@ filegroup(
":package-srcs",
"//pkg/kubectl/cmd/auth:all-srcs",
"//pkg/kubectl/cmd/config:all-srcs",
"//pkg/kubectl/cmd/resource:all-srcs",
"//pkg/kubectl/cmd/rollout:all-srcs",
"//pkg/kubectl/cmd/set:all-srcs",
"//pkg/kubectl/cmd/templates:all-srcs",

View File

@ -65,14 +65,16 @@ type AnnotateOptions struct {
var (
annotateLong = templates.LongDesc(`
Update the annotations on one or more resources.
Update the annotations on one or more resources
* An annotation is a key/value pair that can hold larger (compared to a label), and possibly not human-readable, data.
* It is intended to store non-identifying auxiliary data, especially data manipulated by tools and system extensions.
* If --overwrite is true, then existing annotations can be overwritten, otherwise attempting to overwrite an annotation will result in an error.
* If --resource-version is specified, then updates will use this resource version, otherwise the existing resource-version will be used.
All Kubernetes objects support the ability to store additional data with the object as
annotations. Annotations are key/value pairs that can be larger than labels and include
arbitrary string values such as structured JSON. Tools and system extensions may use
annotations to store their own data.
` + validResources)
Attempting to set an annotation that already exists will fail unless --overwrite is set.
If --resource-version is specified and does not match the current resource version on
the server the command will fail.`)
annotateExample = templates.Examples(i18n.T(`
# Update pod 'foo' with the annotation 'description' and the value 'my frontend'.
@ -113,7 +115,7 @@ func NewCmdAnnotate(f cmdutil.Factory, out io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "annotate [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]",
Short: i18n.T("Update the annotations on a resource"),
Long: annotateLong,
Long: annotateLong + "\n\n" + cmdutil.ValidResourceTypeList(f),
Example: annotateExample,
Run: func(cmd *cobra.Command, args []string) {
if err := options.Complete(out, cmd, args); err != nil {

View File

@ -24,6 +24,7 @@ import (
"k8s.io/client-go/tools/clientcmd"
"k8s.io/kubernetes/pkg/kubectl/cmd/auth"
cmdconfig "k8s.io/kubernetes/pkg/kubectl/cmd/config"
"k8s.io/kubernetes/pkg/kubectl/cmd/resource"
"k8s.io/kubernetes/pkg/kubectl/cmd/rollout"
"k8s.io/kubernetes/pkg/kubectl/cmd/set"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
@ -199,51 +200,6 @@ __custom_func() {
;;
esac
}
`
// If you add a resource to this list, please also take a look at pkg/kubectl/kubectl.go
// and add a short forms entry in expandResourceShortcut() when appropriate.
// TODO: This should be populated using the discovery information from apiserver.
validResources = `Valid resource types include:
* all
* certificatesigningrequests (aka 'csr')
* clusterrolebindings
* clusterroles
* componentstatuses (aka 'cs')
* configmaps (aka 'cm')
* controllerrevisions
* cronjobs
* customresourcedefinition (aka 'crd')
* daemonsets (aka 'ds')
* deployments (aka 'deploy')
* endpoints (aka 'ep')
* events (aka 'ev')
* horizontalpodautoscalers (aka 'hpa')
* ingresses (aka 'ing')
* jobs
* limitranges (aka 'limits')
* namespaces (aka 'ns')
* networkpolicies (aka 'netpol')
* nodes (aka 'no')
* persistentvolumeclaims (aka 'pvc')
* persistentvolumes (aka 'pv')
* poddisruptionbudgets (aka 'pdb')
* podpreset
* pods (aka 'po')
* podsecuritypolicies (aka 'psp')
* podtemplates
* replicasets (aka 'rs')
* replicationcontrollers (aka 'rc')
* resourcequotas (aka 'quota')
* rolebindings
* roles
* secrets
* serviceaccounts (aka 'sa')
* services (aka 'svc')
* statefulsets (aka 'sts')
* storageclasses (aka 'sc')
`
)
@ -297,7 +253,7 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
{
Message: "Basic Commands (Intermediate):",
Commands: []*cobra.Command{
NewCmdGet(f, out, err),
resource.NewCmdGet(f, out, err),
NewCmdExplain(f, out, err),
NewCmdEdit(f, out, err),
NewCmdDelete(f, out, err),

View File

@ -38,6 +38,7 @@ import (
"k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
apitesting "k8s.io/kubernetes/pkg/api/testing"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/scheme"
@ -85,6 +86,52 @@ func defaultClientConfigForVersion(version *schema.GroupVersion) *restclient.Con
}
}
func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList) {
pods := &api.PodList{
ListMeta: metav1.ListMeta{
ResourceVersion: "15",
},
Items: []api.Pod{
{
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10"},
Spec: apitesting.DeepEqualSafePodSpec(),
},
{
ObjectMeta: metav1.ObjectMeta{Name: "bar", Namespace: "test", ResourceVersion: "11"},
Spec: apitesting.DeepEqualSafePodSpec(),
},
},
}
svc := &api.ServiceList{
ListMeta: metav1.ListMeta{
ResourceVersion: "16",
},
Items: []api.Service{
{
ObjectMeta: metav1.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "12"},
Spec: api.ServiceSpec{
SessionAffinity: "None",
Type: api.ServiceTypeClusterIP,
},
},
},
}
rc := &api.ReplicationControllerList{
ListMeta: metav1.ListMeta{
ResourceVersion: "17",
},
Items: []api.ReplicationController{
{
ObjectMeta: metav1.ObjectMeta{Name: "rc1", Namespace: "test", ResourceVersion: "18"},
Spec: api.ReplicationControllerSpec{
Replicas: 1,
},
},
},
}
return pods, svc, rc
}
type testPrinter struct {
Objects []runtime.Object
Err error

View File

@ -37,20 +37,19 @@ import (
)
var (
describe_long = templates.LongDesc(`
Show details of a specific resource or group of resources.
It includes the uninitialized objects, unless --include-uninitialized=false is explicitly set.
This command joins many API calls together to form a detailed description of a
given resource or group of resources.
describeLong = templates.LongDesc(`
Show details of a specific resource or group of resources
Print a detailed description of the selected resources, including related resources such
as events or controllers. You may select a single object by name, all objects of that
type, provide a name prefix, or label selector. For example:
$ kubectl describe TYPE NAME_PREFIX
will first check for an exact match on TYPE and NAME_PREFIX. If no such resource
exists, it will output details for every resource that has a name prefixed with NAME_PREFIX.
exists, it will output details for every resource that has a name prefixed with NAME_PREFIX.`)
` + validResources)
describe_example = templates.Examples(i18n.T(`
describeExample = templates.Examples(i18n.T(`
# Describe a node
kubectl describe nodes kubernetes-node-emt8.c.myproject.internal
@ -83,8 +82,8 @@ func NewCmdDescribe(f cmdutil.Factory, out, cmdErr io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "describe (-f FILENAME | TYPE [NAME_PREFIX | -l label] | TYPE/NAME)",
Short: i18n.T("Show details of a specific resource or group of resources"),
Long: describe_long,
Example: describe_example,
Long: describeLong + "\n\n" + cmdutil.ValidResourceTypeList(f),
Example: describeExample,
Run: func(cmd *cobra.Command, args []string) {
err := RunDescribe(f, out, cmdErr, cmd, args, options, describerSettings)
cmdutil.CheckErr(err)
@ -113,7 +112,7 @@ func RunDescribe(f cmdutil.Factory, out, cmdErr io.Writer, cmd *cobra.Command, a
enforceNamespace = false
}
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(options.Filenames) {
fmt.Fprint(cmdErr, "You must specify the type of resource to describe. ", validResources)
fmt.Fprint(cmdErr, "You must specify the type of resource to describe. ", cmdutil.ValidResourceTypeList(f))
return cmdutil.UsageErrorf(cmd, "Required resource not specified.")
}

View File

@ -32,9 +32,15 @@ import (
var (
explainLong = templates.LongDesc(`
Documentation of resources.
` + validResources)
List the fields for supported resources
This command describes the fields associated with each supported API resource.
Fields are identified via a simple JSONPath identifier:
<type>.<fieldName>[.<fieldName>]
Add the --recursive flag to display all of the fields at once without descriptions.
Information about each field is retrieved from the server in OpenAPI format.`)
explainExamples = templates.Examples(i18n.T(`
# Get the documentation of the resource and its fields
@ -49,7 +55,7 @@ func NewCmdExplain(f cmdutil.Factory, out, cmdErr io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "explain RESOURCE",
Short: i18n.T("Documentation of resources"),
Long: explainLong,
Long: explainLong + "\n\n" + cmdutil.ValidResourceTypeList(f),
Example: explainExamples,
Run: func(cmd *cobra.Command, args []string) {
err := RunExplain(f, out, cmdErr, cmd, args)
@ -65,7 +71,7 @@ func NewCmdExplain(f cmdutil.Factory, out, cmdErr io.Writer) *cobra.Command {
// RunExplain executes the appropriate steps to print a model's documentation
func RunExplain(f cmdutil.Factory, out, cmdErr io.Writer, cmd *cobra.Command, args []string) error {
if len(args) == 0 {
fmt.Fprintf(cmdErr, "You must specify the type of resource to explain. %s\n", validResources)
fmt.Fprintf(cmdErr, "You must specify the type of resource to explain. %s\n", cmdutil.ValidResourceTypeList(f))
return cmdutil.UsageErrorf(cmd, "Required resource not specified.")
}
if len(args) > 1 {

View File

@ -0,0 +1,78 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = ["get.go"],
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/resource",
visibility = ["//visibility:public"],
deps = [
"//pkg/api:go_default_library",
"//pkg/kubectl:go_default_library",
"//pkg/kubectl/cmd/templates:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/cmd/util/openapi:go_default_library",
"//pkg/kubectl/resource:go_default_library",
"//pkg/kubectl/util/i18n:go_default_library",
"//pkg/printers:go_default_library",
"//pkg/util/interrupt:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["get_test.go"],
data = [
"//examples:config",
"//test/fixtures",
],
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/resource",
library = ":go_default_library",
deps = [
"//pkg/api:go_default_library",
"//pkg/api/testapi:go_default_library",
"//pkg/api/testing:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/kubectl/cmd/testing:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/cmd/util/openapi:go_default_library",
"//pkg/kubectl/scheme:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/client-go/dynamic:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/rest/fake:go_default_library",
"//vendor/k8s.io/client-go/rest/watch:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
package resource
import (
"encoding/json"
@ -56,14 +56,17 @@ type GetOptions struct {
var (
getLong = templates.LongDesc(`
Display one or many resources.
` + validResources + `
Display one or many resources
Prints a table of the most important information about the specified resources.
You can filter the list using a label selector and the --selector flag. If the
desired resource type is namespaced you will only see results in your current
namespace unless you pass --all-namespaces.
This command will hide resources that have completed, such as pods that are
in the Succeeded or Failed phases. You can see the full results for any
resource by providing the '--show-all' flag, but this flag does not include
the uninitialized objects by default, unless '--include-uninitialized' is explicitly set.
resource by providing the --show-all flag. Uninitialized objects are not
shown unless --include-uninitialized is passed.
By specifying the output as 'template' and providing a Go template as the value
of the --template flag, you can filter the attributes of the fetched resources.`)
@ -120,7 +123,7 @@ func NewCmdGet(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Comman
cmd := &cobra.Command{
Use: "get [(-o|--output=)json|yaml|wide|custom-columns=...|custom-columns-file=...|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=...] (TYPE [NAME | -l label] | TYPE/NAME ...) [flags]",
Short: i18n.T("Display one or many resources"),
Long: getLong,
Long: getLong + "\n\n" + cmdutil.ValidResourceTypeList(f),
Example: getExample,
Run: func(cmd *cobra.Command, args []string) {
err := RunGet(f, out, errOut, cmd, args, options)
@ -191,7 +194,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [
}
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(options.Filenames) {
fmt.Fprint(errOut, "You must specify the type of resource to get. ", validResources)
fmt.Fprint(errOut, "You must specify the type of resource to get. ", cmdutil.ValidResourceTypeList(f))
fullCmdName := cmd.Parent().CommandPath()
usageString := "Required resource not specified."

View File

@ -14,11 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
package resource
import (
"bytes"
encjson "encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
@ -35,6 +36,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/serializer/json"
"k8s.io/apimachinery/pkg/runtime/serializer/streaming"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/dynamic"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
restclientwatch "k8s.io/client-go/rest/watch"
@ -44,6 +46,7 @@ import (
apitesting "k8s.io/kubernetes/pkg/api/testing"
"k8s.io/kubernetes/pkg/api/v1"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
"k8s.io/kubernetes/pkg/kubectl/scheme"
)
@ -55,6 +58,75 @@ func init() {
scheme.Scheme.AddConversionFuncs(v1.Convert_v1_PodSecurityContext_To_api_PodSecurityContext)
}
var unstructuredSerializer = dynamic.ContentConfig().NegotiatedSerializer
func defaultHeader() http.Header {
header := http.Header{}
header.Set("Content-Type", runtime.ContentTypeJSON)
return header
}
func defaultClientConfig() *restclient.Config {
return &restclient.Config{
APIPath: "/api",
ContentConfig: restclient.ContentConfig{
NegotiatedSerializer: scheme.Codecs,
ContentType: runtime.ContentTypeJSON,
GroupVersion: &scheme.Registry.GroupOrDie(api.GroupName).GroupVersion,
},
}
}
func defaultClientConfigForVersion(version *schema.GroupVersion) *restclient.Config {
return &restclient.Config{
APIPath: "/api",
ContentConfig: restclient.ContentConfig{
NegotiatedSerializer: scheme.Codecs,
ContentType: runtime.ContentTypeJSON,
GroupVersion: version,
},
}
}
type testPrinter struct {
Objects []runtime.Object
Err error
GenericPrinter bool
}
func (t *testPrinter) PrintObj(obj runtime.Object, out io.Writer) error {
t.Objects = append(t.Objects, obj)
fmt.Fprintf(out, "%#v", obj)
return t.Err
}
// TODO: implement HandledResources()
func (t *testPrinter) HandledResources() []string {
return []string{}
}
func (t *testPrinter) AfterPrint(output io.Writer, res string) error {
return nil
}
func (t *testPrinter) IsGeneric() bool {
return t.GenericPrinter
}
func objBody(codec runtime.Codec, obj runtime.Object) io.ReadCloser {
return ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, obj))))
}
func stringBody(body string) io.ReadCloser {
return ioutil.NopCloser(bytes.NewReader([]byte(body)))
}
func initTestErrorHandler(t *testing.T) {
cmdutil.BehaviorOnFatal(func(str string, code int) {
t.Errorf("Error running command (exit code %d): %s", code, str)
})
}
func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList) {
pods := &api.PodList{
ListMeta: metav1.ListMeta{
@ -295,7 +367,7 @@ func TestGetObjectsFiltered(t *testing.T) {
{args: []string{"pods"}, flags: map[string]string{"show-all": "true"}, resp: pods, expect: []runtime.Object{first, second}},
{args: []string{"pods/foo"}, resp: first, expect: []runtime.Object{first}, genericPrinter: true},
{args: []string{"pods"}, flags: map[string]string{"output": "yaml"}, resp: pods, expect: []runtime.Object{second}},
{args: []string{}, flags: map[string]string{"filename": "../../../examples/storage/cassandra/cassandra-controller.yaml"}, resp: pods, expect: []runtime.Object{first, second}},
{args: []string{}, flags: map[string]string{"filename": "../../../../examples/storage/cassandra/cassandra-controller.yaml"}, resp: pods, expect: []runtime.Object{first, second}},
{args: []string{"pods"}, resp: pods, expect: []runtime.Object{second}},
{args: []string{"pods"}, flags: map[string]string{"show-all": "true", "output": "yaml"}, resp: pods, expect: []runtime.Object{first, second}},
@ -467,7 +539,7 @@ func TestGetObjectsIdentifiedByFile(t *testing.T) {
cmd := NewCmdGet(f, buf, errBuf)
cmd.SetOutput(buf)
cmd.Flags().Set("filename", "../../../examples/storage/cassandra/cassandra-controller.yaml")
cmd.Flags().Set("filename", "../../../../examples/storage/cassandra/cassandra-controller.yaml")
cmd.Run(cmd, []string{})
expected := []runtime.Object{&pods.Items[0]}
@ -955,9 +1027,8 @@ func TestWatchSelector(t *testing.T) {
case "/namespaces/test/pods":
if req.URL.Query().Get("watch") == "true" {
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: watchBody(codec, events[2:])}, nil
} else {
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, podList)}, nil
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, podList)}, nil
default:
t.Fatalf("request url: %#v,and request: %#v", req.URL, req)
return nil, nil
@ -1055,7 +1126,7 @@ func TestWatchResourceIdentifiedByFile(t *testing.T) {
cmd.SetOutput(buf)
cmd.Flags().Set("watch", "true")
cmd.Flags().Set("filename", "../../../examples/storage/cassandra/cassandra-controller.yaml")
cmd.Flags().Set("filename", "../../../../examples/storage/cassandra/cassandra-controller.yaml")
cmd.Run(cmd, []string{})
expected := []runtime.Object{&pods[1], events[2].Object, events[3].Object}
@ -1125,9 +1196,8 @@ func TestWatchOnlyList(t *testing.T) {
case "/namespaces/test/pods":
if req.URL.Query().Get("watch") == "true" {
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: watchBody(codec, events[2:])}, nil
} else {
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, podList)}, nil
}
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, podList)}, nil
default:
t.Fatalf("request url: %#v,and request: %#v", req.URL, req)
return nil, nil

View File

@ -33,6 +33,7 @@ go_library(
"//pkg/client/unversioned:go_default_library",
"//pkg/controller:go_default_library",
"//pkg/kubectl:go_default_library",
"//pkg/kubectl/cmd/templates:go_default_library",
"//pkg/kubectl/cmd/util/openapi:go_default_library",
"//pkg/kubectl/cmd/util/openapi/validation:go_default_library",
"//pkg/kubectl/plugins:go_default_library",

View File

@ -24,6 +24,7 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/printers"
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
@ -216,3 +217,53 @@ func maybeWrapSortingPrinter(cmd *cobra.Command, printer printers.ResourcePrinte
}
return printer
}
// ValidResourceTypeList returns a multi-line string containing the valid resources. May
// be called before the factory is initialized.
// TODO: This function implementation should be replaced with a real implementation from the
// discovery service.
func ValidResourceTypeList(f ClientAccessFactory) string {
// TODO: Should attempt to use the cached discovery list or fallback to a static list
// that is calculated from code compiled into the factory.
return templates.LongDesc(`Valid resource types include:
* all
* certificatesigningrequests (aka 'csr')
* clusterrolebindings
* clusterroles
* componentstatuses (aka 'cs')
* configmaps (aka 'cm')
* controllerrevisions
* cronjobs
* customresourcedefinition (aka 'crd')
* daemonsets (aka 'ds')
* deployments (aka 'deploy')
* endpoints (aka 'ep')
* events (aka 'ev')
* horizontalpodautoscalers (aka 'hpa')
* ingresses (aka 'ing')
* jobs
* limitranges (aka 'limits')
* namespaces (aka 'ns')
* networkpolicies (aka 'netpol')
* nodes (aka 'no')
* persistentvolumeclaims (aka 'pvc')
* persistentvolumes (aka 'pv')
* poddisruptionbudgets (aka 'pdb')
* podpreset
* pods (aka 'po')
* podsecuritypolicies (aka 'psp')
* podtemplates
* replicasets (aka 'rs')
* replicationcontrollers (aka 'rc')
* resourcequotas (aka 'quota')
* rolebindings
* roles
* secrets
* serviceaccounts (aka 'sa')
* services (aka 'svc')
* statefulsets (aka 'sts')
* storageclasses (aka 'sc')
`)
}