diff --git a/cmd/config/cmd/cat.go b/cmd/config/cmd/cat.go index 2d2138416..1dd95ca14 100644 --- a/cmd/config/cmd/cat.go +++ b/cmd/config/cmd/cat.go @@ -5,9 +5,11 @@ package cmd import ( "fmt" + "os" "github.com/spf13/cobra" "sigs.k8s.io/kustomize/cmd/config/cmddocs/commands" + "sigs.k8s.io/kustomize/kyaml/errors" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio/filters" "sigs.k8s.io/kustomize/kyaml/yaml" @@ -45,6 +47,8 @@ func GetCatRunner(name string) *CatRunner { "if true, include local-config in the output.") c.Flags().BoolVar(&r.ExcludeNonLocal, "exclude-non-local", false, "if true, exclude non-local-config in the output.") + c.Flags().StringVar(&r.OutputDest, "dest", "", + "if specified, write output to a file rather than stdout") r.Command = c return r } @@ -61,6 +65,7 @@ type CatRunner struct { WrapKind string WrapApiVersion string FunctionConfig string + OutputDest string Styles []string StripComments bool IncludeLocal bool @@ -106,9 +111,19 @@ func (r *CatRunner) runE(c *cobra.Command, args []string) error { fltr = append(fltr, filters.StripCommentsFilter{}) } + var out = c.OutOrStdout() + if r.OutputDest != "" { + o, err := os.Create(r.OutputDest) + if err != nil { + return handleError(c, errors.Wrap(err)) + } + defer o.Close() + out = o + } + var outputs []kio.Writer outputs = append(outputs, kio.ByteWriter{ - Writer: c.OutOrStdout(), + Writer: out, KeepReaderAnnotations: r.KeepAnnotations, WrappingKind: r.WrapKind, WrappingApiVersion: r.WrapApiVersion, diff --git a/cmd/config/cmd/cat_test.go b/cmd/config/cmd/cat_test.go index fd4786c16..a6c11c769 100644 --- a/cmd/config/cmd/cat_test.go +++ b/cmd/config/cmd/cat_test.go @@ -325,3 +325,246 @@ spec: return } } + +func TestCmd_outputTruncateFile(t *testing.T) { + d, err := ioutil.TempDir("", "kustomize-cat-test") + if !assert.NoError(t, err) { + return + } + defer os.RemoveAll(d) + + err = ioutil.WriteFile(filepath.Join(d, "f1.yaml"), []byte(` +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 +`), 0600) + if !assert.NoError(t, err) { + return + } + err = ioutil.WriteFile(filepath.Join(d, "f2.yaml"), []byte(` +apiVersion: v1 +kind: Abstraction +metadata: + name: foo + configFn: + container: + image: gcr.io/example/reconciler:v1 + annotations: + 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 +`), 0600) + if !assert.NoError(t, err) { + return + } + + f, err := ioutil.TempFile("", "kustomize-cat-test-dest") + if !assert.NoError(t, err) { + return + } + defer os.RemoveAll(d) + + // fmt the files + b := &bytes.Buffer{} + r := cmd.GetCatRunner("") + r.Command.SetArgs([]string{d, "--dest", f.Name()}) + r.Command.SetOut(b) + if !assert.NoError(t, r.Command.Execute()) { + return + } + + if !assert.Equal(t, ``, b.String()) { + return + } + + actual, err := ioutil.ReadFile(f.Name()) + if !assert.NoError(t, err) { + return + } + if !assert.Equal(t, `kind: Deployment +metadata: + labels: + app: nginx2 + name: foo + annotations: + app: nginx2 + config.kubernetes.io/package: . + config.kubernetes.io/path: f1.yaml +spec: + replicas: 1 +--- +kind: Service +metadata: + name: foo + annotations: + app: nginx + config.kubernetes.io/package: . + config.kubernetes.io/path: f1.yaml +spec: + selector: + app: nginx +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: bar + labels: + app: nginx + annotations: + app: nginx + config.kubernetes.io/package: . + config.kubernetes.io/path: f2.yaml +spec: + replicas: 3 +`, string(actual)) { + return + } +} + +func TestCmd_outputCreateFile(t *testing.T) { + d, err := ioutil.TempDir("", "kustomize-cat-test") + if !assert.NoError(t, err) { + return + } + defer os.RemoveAll(d) + + err = ioutil.WriteFile(filepath.Join(d, "f1.yaml"), []byte(` +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 +`), 0600) + if !assert.NoError(t, err) { + return + } + err = ioutil.WriteFile(filepath.Join(d, "f2.yaml"), []byte(` +apiVersion: v1 +kind: Abstraction +metadata: + name: foo + configFn: + container: + image: gcr.io/example/reconciler:v1 + annotations: + 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 +`), 0600) + if !assert.NoError(t, err) { + return + } + + d2, err := ioutil.TempDir("", "kustomize-cat-test-dest") + if !assert.NoError(t, err) { + return + } + defer os.RemoveAll(d2) + f := filepath.Join(d2, "output.yaml") + + // fmt the files + b := &bytes.Buffer{} + r := cmd.GetCatRunner("") + r.Command.SetArgs([]string{d, "--dest", f}) + r.Command.SetOut(b) + if !assert.NoError(t, r.Command.Execute()) { + return + } + + if !assert.Equal(t, ``, b.String()) { + return + } + + actual, err := ioutil.ReadFile(f) + if !assert.NoError(t, err) { + return + } + if !assert.Equal(t, `kind: Deployment +metadata: + labels: + app: nginx2 + name: foo + annotations: + app: nginx2 + config.kubernetes.io/package: . + config.kubernetes.io/path: f1.yaml +spec: + replicas: 1 +--- +kind: Service +metadata: + name: foo + annotations: + app: nginx + config.kubernetes.io/package: . + config.kubernetes.io/path: f1.yaml +spec: + selector: + app: nginx +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: bar + labels: + app: nginx + annotations: + app: nginx + config.kubernetes.io/package: . + config.kubernetes.io/path: f2.yaml +spec: + replicas: 3 +`, string(actual)) { + return + } +}