Skip to content

Commit 4123a61

Browse files
committed
Add the client side bits of kubectl export
1 parent 4ca66d2 commit 4123a61

14 files changed

Lines changed: 69 additions & 23 deletions

File tree

contrib/completions/bash/kubectl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ _kubectl_get()
265265
flags_completion=()
266266

267267
flags+=("--all-namespaces")
268+
flags+=("--export")
268269
flags+=("--filename=")
269270
flags_with_completion+=("--filename")
270271
flags_completion+=("__handle_filename_extension_flag json|yaml|yml")

docs/man/man1/kubectl-get.1

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ of the \-\-template flag, you can filter the attributes of the fetched resource(
3232
\fB\-\-all\-namespaces\fP=false
3333
If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with \-\-namespace.
3434

35+
.PP
36+
\fB\-\-export\fP=false
37+
If true, use 'export' for the resources. Exported resources are stripped of cluster\-specific information.
38+
3539
.PP
3640
\fB\-f\fP, \fB\-\-filename\fP=[]
3741
Filename, directory, or URL to a file identifying the resource to get from a server.

docs/user-guide/kubectl/kubectl_get.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ $ kubectl get rc/web service/frontend pods/web-pod-13je7
8686

8787
```
8888
--all-namespaces[=false]: If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.
89+
--export[=false]: If true, use 'export' for the resources. Exported resources are stripped of cluster-specific information.
8990
-f, --filename=[]: Filename, directory, or URL to a file identifying the resource to get from a server.
9091
-L, --label-columns=[]: Accepts a comma separated list of labels that are going to be presented as columns. Names are case-sensitive. You can also use multiple flag statements like -L label1 -L label2...
9192
--no-headers[=false]: When using the default output, don't print headers.
@@ -131,7 +132,7 @@ $ kubectl get rc/web service/frontend pods/web-pod-13je7
131132

132133
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
133134

134-
###### Auto generated by spf13/cobra on 8-Dec-2015
135+
###### Auto generated by spf13/cobra on 22-Dec-2015
135136

136137
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
137138
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_get.md?pixel)]()

hack/lib/test.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ kube::test::get_object_assert() {
3030
local object=$1
3131
local request=$2
3232
local expected=$3
33+
local args=${4:-}
3334

34-
res=$(eval kubectl get "${kube_flags[@]}" $object -o go-template=\"$request\")
35+
res=$(eval kubectl ${args} get "${kube_flags[@]}" $object -o go-template=\"$request\")
3536

3637
if [[ "$res" =~ ^$expected$ ]]; then
3738
echo -n ${green}

hack/test-cmd.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,9 @@ runTests() {
287287
# Describe command (resource only) should print detailed information
288288
kube::test::describe_resource_assert pods "Name:" "Image(s):" "Node:" "Labels:" "Status:" "Controllers"
289289

290+
### Validate Export ###
291+
kube::test::get_object_assert 'pods/valid-pod' "{{.metadata.namespace}} {{.metadata.name}}" '<no value> valid-pod' "--export=true"
292+
290293
### Dump current valid-pod POD
291294
output_pod=$(kubectl get pod valid-pod -o yaml --output-version=v1 "${kube_flags[@]}")
292295

pkg/kubectl/cmd/apply_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ func walkMapPath(t *testing.T, start map[string]interface{}, path []string) map[
170170
}
171171

172172
func TestApplyObject(t *testing.T) {
173+
initTestErrorHandler(t)
173174
nameRC, currentRC := readAndAnnotateReplicationController(t, filenameRC)
174175
pathRC := "/namespaces/test/replicationcontrollers/" + nameRC
175176

pkg/kubectl/cmd/cmd_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ import (
4141
"k8s.io/kubernetes/pkg/util"
4242
)
4343

44+
func initTestErrorHandler(t *testing.T) {
45+
cmdutil.BehaviorOnFatal(func(str string) {
46+
t.Errorf("Error running command: %s", str)
47+
})
48+
}
49+
4450
type internalType struct {
4551
Kind string
4652
APIVersion string

pkg/kubectl/cmd/create_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
)
2828

2929
func TestExtraArgsFail(t *testing.T) {
30+
initTestErrorHandler(t)
3031
buf := bytes.NewBuffer([]byte{})
3132

3233
f, _, _ := NewAPIFactory()
@@ -37,6 +38,7 @@ func TestExtraArgsFail(t *testing.T) {
3738
}
3839

3940
func TestCreateObject(t *testing.T) {
41+
initTestErrorHandler(t)
4042
_, _, rc := testData()
4143
rc.Items[0].Name = "redis-master-controller"
4244

@@ -69,6 +71,7 @@ func TestCreateObject(t *testing.T) {
6971
}
7072

7173
func TestCreateMultipleObject(t *testing.T) {
74+
initTestErrorHandler(t)
7275
_, svc, rc := testData()
7376

7477
f, tf, codec := NewAPIFactory()
@@ -103,6 +106,7 @@ func TestCreateMultipleObject(t *testing.T) {
103106
}
104107

105108
func TestCreateDirectory(t *testing.T) {
109+
initTestErrorHandler(t)
106110
_, svc, rc := testData()
107111
rc.Items[0].Name = "name"
108112

@@ -136,6 +140,7 @@ func TestCreateDirectory(t *testing.T) {
136140
}
137141

138142
func TestPrintObjectSpecificMessage(t *testing.T) {
143+
initTestErrorHandler(t)
139144
tests := []struct {
140145
obj runtime.Object
141146
expectOutput bool
@@ -170,6 +175,7 @@ func TestPrintObjectSpecificMessage(t *testing.T) {
170175
}
171176

172177
func TestMakePortsString(t *testing.T) {
178+
initTestErrorHandler(t)
173179
tests := []struct {
174180
ports []api.ServicePort
175181
useNodePort bool

pkg/kubectl/cmd/get.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ func NewCmdGet(f *cmdutil.Factory, out io.Writer) *cobra.Command {
101101
cmd.Flags().Bool("watch-only", false, "Watch for changes to the requested object(s), without listing/getting first.")
102102
cmd.Flags().Bool("all-namespaces", false, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.")
103103
cmd.Flags().StringSliceP("label-columns", "L", []string{}, "Accepts a comma separated list of labels that are going to be presented as columns. Names are case-sensitive. You can also use multiple flag statements like -L label1 -L label2...")
104+
cmd.Flags().Bool("export", false, "If true, use 'export' for the resources. Exported resources are stripped of cluster-specific information.")
104105
usage := "Filename, directory, or URL to a file identifying the resource to get from a server."
105106
kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
106107
return cmd
@@ -131,6 +132,7 @@ func RunGet(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string
131132
if len(options.Filenames) > 0 || argsHasNames {
132133
cmd.Flag("show-all").Value.Set("true")
133134
}
135+
export := cmdutil.GetFlagBool(cmd, "export")
134136

135137
// handle watch separately since we cannot watch multiple resource types
136138
isWatch, isWatchOnly := cmdutil.GetFlagBool(cmd, "watch"), cmdutil.GetFlagBool(cmd, "watch-only")
@@ -139,6 +141,7 @@ func RunGet(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string
139141
NamespaceParam(cmdNamespace).DefaultNamespace().AllNamespaces(allNamespaces).
140142
FilenameParam(enforceNamespace, options.Filenames...).
141143
SelectorParam(selector).
144+
ExportParam(export).
142145
ResourceTypeOrNameArgs(true, args...).
143146
SingleResourceType().
144147
Latest().
@@ -193,6 +196,7 @@ func RunGet(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string
193196
NamespaceParam(cmdNamespace).DefaultNamespace().AllNamespaces(allNamespaces).
194197
FilenameParam(enforceNamespace, options.Filenames...).
195198
SelectorParam(selector).
199+
ExportParam(export).
196200
ResourceTypeOrNameArgs(true, args...).
197201
ContinueOnError().
198202
Latest()

pkg/kubectl/resource/builder.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ type Builder struct {
6868
singleResourceType bool
6969
continueOnError bool
7070

71+
export bool
72+
7173
schema validation.Schema
7274
}
7375

@@ -234,6 +236,12 @@ func (b *Builder) Selector(selector labels.Selector) *Builder {
234236
return b
235237
}
236238

239+
// ExportParam accepts the export boolean for these resources
240+
func (b *Builder) ExportParam(export bool) *Builder {
241+
b.export = export
242+
return b
243+
}
244+
237245
// NamespaceParam accepts the namespace that these resources should be
238246
// considered under from - used by DefaultNamespace() and RequireNamespace()
239247
func (b *Builder) NamespaceParam(namespace string) *Builder {
@@ -512,7 +520,7 @@ func (b *Builder) visitorResult() *Result {
512520
if mapping.Scope.Name() != meta.RESTScopeNameNamespace {
513521
selectorNamespace = ""
514522
}
515-
visitors = append(visitors, NewSelector(client, mapping, selectorNamespace, b.selector))
523+
visitors = append(visitors, NewSelector(client, mapping, selectorNamespace, b.selector, b.export))
516524
}
517525
if b.continueOnError {
518526
return &Result{visitor: EagerVisitorList(visitors), sources: visitors}
@@ -570,7 +578,7 @@ func (b *Builder) visitorResult() *Result {
570578
}
571579
}
572580

573-
info := NewInfo(client, mapping, selectorNamespace, tuple.Name)
581+
info := NewInfo(client, mapping, selectorNamespace, tuple.Name, b.export)
574582
items = append(items, info)
575583
}
576584

@@ -619,7 +627,7 @@ func (b *Builder) visitorResult() *Result {
619627

620628
visitors := []Visitor{}
621629
for _, name := range b.names {
622-
info := NewInfo(client, mapping, selectorNamespace, name)
630+
info := NewInfo(client, mapping, selectorNamespace, name, b.export)
623631
visitors = append(visitors, info)
624632
}
625633
return &Result{singular: isSingular, visitor: VisitorList(visitors), sources: visitors}

0 commit comments

Comments
 (0)