cmd/config: support for stdin/stdout in source/sink

This commit is contained in:
Phillip Wittrock
2020-02-05 16:08:02 -08:00
parent daa9504890
commit 90e1dbe5d0
7 changed files with 211 additions and 24 deletions

View File

@@ -6,10 +6,10 @@
[Alpha] Implement a Sink by writing input to a local directory.
kustomize config sink DIR
kustomize config sink [DIR]
DIR:
Path to local directory.
Path to local directory. If unspecified, sink will write to stdout as if it were a single file.
`sink` writes its input to a directory

View File

@@ -6,10 +6,11 @@
[Alpha] Implement a Source by reading a local directory.
kustomize config source DIR
kustomize config source DIR...
DIR:
Path to local directory.
One or more paths to local directories. Contents from directories will be concatenated.
If no directories are provided, source will read from stdin as if it were a single file.
`source` emits configuration to act as input to a function

View File

@@ -7,6 +7,7 @@ import (
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/kio/kioutil"
)
// GetSinkRunner returns a command for Sink.
@@ -18,7 +19,7 @@ func GetSinkRunner(name string) *SinkRunner {
Long: commands.SinkLong,
Example: commands.SinkExamples,
RunE: r.runE,
Args: cobra.ExactArgs(1),
Args: cobra.MaximumNArgs(1),
}
fixDocs(name, c)
r.Command = c
@@ -35,14 +36,18 @@ type SinkRunner struct {
}
func (r *SinkRunner) runE(c *cobra.Command, args []string) error {
var outputs []kio.Writer
if len(args) == 1 {
outputs = []kio.Writer{&kio.LocalPackageWriter{PackagePath: args[0]}}
} else {
outputs = []kio.Writer{&kio.ByteWriter{
Writer: c.OutOrStdout(),
ClearAnnotations: []string{kioutil.PathAnnotation}},
}
}
err := kio.Pipeline{
Inputs: []kio.Reader{&kio.ByteReader{Reader: c.InOrStdin()}},
Outputs: []kio.Writer{
&kio.LocalPackageWriter{
PackagePath: args[0],
ClearAnnotations: []string{"config.kubernetes.io/path"},
},
},
}.Execute()
Inputs: []kio.Reader{&kio.ByteReader{Reader: c.InOrStdin()}},
Outputs: outputs}.Execute()
return handleError(c, err)
}

View File

@@ -21,8 +21,6 @@ func TestSinkCommand(t *testing.T) {
}
defer os.RemoveAll(d)
// fmt the files
b := &bytes.Buffer{}
r := commands.GetSinkRunner("")
r.Command.SetIn(bytes.NewBufferString(`apiVersion: config.kubernetes.io/v1alpha1
kind: ResourceList
@@ -75,7 +73,6 @@ items:
replicas: 3
`))
r.Command.SetArgs([]string{d})
r.Command.SetOut(b)
if !assert.NoError(t, r.Command.Execute()) {
t.FailNow()
}
@@ -138,3 +135,117 @@ spec:
t.FailNow()
}
}
func TestSinkCommand_Stdout(t *testing.T) {
d, err := ioutil.TempDir("", "kustomize-source-test")
if !assert.NoError(t, err) {
t.FailNow()
}
defer os.RemoveAll(d)
// fmt the files
out := &bytes.Buffer{}
r := commands.GetSinkRunner("")
r.Command.SetIn(bytes.NewBufferString(`apiVersion: config.kubernetes.io/v1alpha1
kind: ResourceList
items:
- kind: Deployment
metadata:
labels:
app: nginx2
name: foo
annotations:
app: nginx2
config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'f1.yaml'
spec:
replicas: 1
- kind: Service
metadata:
name: foo
annotations:
app: nginx
config.kubernetes.io/index: '1'
config.kubernetes.io/path: 'f1.yaml'
spec:
selector:
app: nginx
- apiVersion: v1
kind: Abstraction
metadata:
name: foo
annotations:
config.kubernetes.io/function: |
container:
image: gcr.io/example/reconciler:v1
config.kubernetes.io/local-config: "true"
config.kubernetes.io/index: '0'
config.kubernetes.io/path: 'f2.yaml'
spec:
replicas: 3
- apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: bar
annotations:
app: nginx
config.kubernetes.io/index: '1'
config.kubernetes.io/path: 'f2.yaml'
spec:
replicas: 3
`))
r.Command.SetOut(out)
r.Command.SetArgs([]string{})
if !assert.NoError(t, r.Command.Execute()) {
t.FailNow()
}
expected := `kind: Deployment
metadata:
labels:
app: nginx2
name: foo
annotations:
app: nginx2
spec:
replicas: 1
---
kind: Service
metadata:
name: foo
annotations:
app: nginx
spec:
selector:
app: nginx
---
apiVersion: v1
kind: Abstraction
metadata:
name: foo
annotations:
config.kubernetes.io/function: |
container:
image: gcr.io/example/reconciler:v1
config.kubernetes.io/local-config: "true"
spec:
replicas: 3
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: bar
annotations:
app: nginx
spec:
replicas: 3
`
if !assert.Equal(t, expected, out.String()) {
t.FailNow()
}
}

View File

@@ -21,7 +21,6 @@ func GetSourceRunner(name string) *SourceRunner {
Long: commands.SourceLong,
Example: commands.SourceExamples,
RunE: r.runE,
Args: cobra.ExactArgs(1),
}
fixDocs(name, c)
c.Flags().StringVar(&r.WrapKind, "wrap-kind", kio.ResourceListKind,
@@ -70,8 +69,14 @@ func (r *SourceRunner) runE(c *cobra.Command, args []string) error {
FunctionConfig: functionConfig,
})
err := kio.Pipeline{
Inputs: []kio.Reader{kio.LocalPackageReader{PackagePath: args[0]}},
Outputs: outputs}.Execute()
var inputs []kio.Reader
for _, a := range args {
inputs = append(inputs, kio.LocalPackageReader{PackagePath: a})
}
if len(inputs) == 0 {
inputs = []kio.Reader{&kio.ByteReader{Reader: c.InOrStdin()}}
}
err := kio.Pipeline{Inputs: inputs, Outputs: outputs}.Execute()
return handleError(c, err)
}

View File

@@ -134,3 +134,67 @@ items:
return
}
}
func TestSourceCommand_Stdin(t *testing.T) {
d, err := ioutil.TempDir("", "kustomize-source-test")
if !assert.NoError(t, err) {
return
}
defer os.RemoveAll(d)
in := bytes.NewBufferString(`
kind: Deployment
metadata:
labels:
app: nginx2
name: foo
annotations:
app: nginx2
spec:
replicas: 1
---
kind: Service
metadata:
name: foo
annotations:
app: nginx
spec:
selector:
app: nginx
`)
out := &bytes.Buffer{}
r := commands.GetSourceRunner("")
r.Command.SetArgs([]string{})
r.Command.SetIn(in)
r.Command.SetOut(out)
if !assert.NoError(t, r.Command.Execute()) {
return
}
if !assert.Equal(t, `apiVersion: config.kubernetes.io/v1alpha1
kind: ResourceList
items:
- kind: Deployment
metadata:
labels:
app: nginx2
name: foo
annotations:
app: nginx2
config.kubernetes.io/index: '0'
spec:
replicas: 1
- kind: Service
metadata:
name: foo
annotations:
app: nginx
config.kubernetes.io/index: '1'
spec:
selector:
app: nginx
`, out.String()) {
return
}
}

View File

@@ -350,10 +350,10 @@ var SinkShort = `[Alpha] Implement a Sink by writing input to a local directory.
var SinkLong = `
[Alpha] Implement a Sink by writing input to a local directory.
kustomize config sink DIR
kustomize config sink [DIR]
DIR:
Path to local directory.
Path to local directory. If unspecified, sink will write to stdout as if it were a single file.
` + "`" + `sink` + "`" + ` writes its input to a directory
`
@@ -364,10 +364,11 @@ var SourceShort = `[Alpha] Implement a Source by reading a local directory.`
var SourceLong = `
[Alpha] Implement a Source by reading a local directory.
kustomize config source DIR
kustomize config source DIR...
DIR:
Path to local directory.
One or more paths to local directories. Contents from directories will be concatenated.
If no directories are provided, source will read from stdin as if it were a single file.
` + "`" + `source` + "`" + ` emits configuration to act as input to a function
`