Annotate With Subpackages

Delete Setters And Subst With Subpkgs
This commit is contained in:
Phani Teja Marupaka
2020-09-02 13:33:50 -07:00
parent 678ae12115
commit 0dc36a4f7c
9 changed files with 373 additions and 85 deletions

View File

@@ -4,9 +4,12 @@
package commands package commands
import ( import (
"fmt"
"io"
"strings" "strings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands" "sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/kyaml/errors" "sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio"
@@ -31,6 +34,8 @@ func NewAnnotateRunner(parent string) *AnnotateRunner {
c.Flags().StringVar(&r.Name, "name", "", "Resource name to annotate") c.Flags().StringVar(&r.Name, "name", "", "Resource name to annotate")
c.Flags().StringVar(&r.Namespace, "namespace", "", "Resource namespace to annotate") c.Flags().StringVar(&r.Namespace, "namespace", "", "Resource namespace to annotate")
c.Flags().StringSliceVar(&r.Values, "kv", []string{}, "annotation as KEY=VALUE") c.Flags().StringSliceVar(&r.Values, "kv", []string{}, "annotation as KEY=VALUE")
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", false,
"add annotations recursively in all the nested subpackages")
return r return r
} }
@@ -39,13 +44,14 @@ func AnnotateCommand(parent string) *cobra.Command {
} }
type AnnotateRunner struct { type AnnotateRunner struct {
Command *cobra.Command Command *cobra.Command
Values []string Values []string
Kind string Kind string
Name string Name string
ApiVersion string ApiVersion string
Namespace string Namespace string
Path string Path string
RecurseSubPackages bool
} }
func (r *AnnotateRunner) runE(c *cobra.Command, args []string) error { func (r *AnnotateRunner) runE(c *cobra.Command, args []string) error {
@@ -55,16 +61,54 @@ func (r *AnnotateRunner) runE(c *cobra.Command, args []string) error {
rw := &kio.ByteReadWriter{Reader: c.InOrStdin(), Writer: c.OutOrStdout()} rw := &kio.ByteReadWriter{Reader: c.InOrStdin(), Writer: c.OutOrStdout()}
input = []kio.Reader{rw} input = []kio.Reader{rw}
output = []kio.Writer{rw} output = []kio.Writer{rw}
} else {
rw := &kio.LocalPackageReadWriter{PackagePath: args[0], NoDeleteFiles: true} return handleError(c, kio.Pipeline{
input = []kio.Reader{rw} Inputs: input,
output = []kio.Writer{rw} Filters: []kio.Filter{r},
Outputs: output,
}.Execute())
} }
return handleError(c, kio.Pipeline{
e := executeCmdOnPkgs{
writer: c.OutOrStdout(),
needOpenAPI: false,
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
rootPkgPath: args[0],
}
err := e.execute()
if err != nil {
return err
}
return nil
}
func (r *AnnotateRunner) executeCmd(w io.Writer, pkgPath string) error {
openAPIFileName, err := ext.OpenAPIFileName()
if err != nil {
return err
}
rw := &kio.LocalPackageReadWriter{PackagePath: pkgPath, NoDeleteFiles: true, PackageFileName: openAPIFileName}
input := []kio.Reader{rw}
output := []kio.Writer{rw}
err = kio.Pipeline{
Inputs: input, Inputs: input,
Filters: []kio.Filter{r}, Filters: []kio.Filter{r},
Outputs: output, Outputs: output,
}.Execute()) }.Execute()
if err != nil {
// return err if there is only package
if !r.RecurseSubPackages {
return err
} else {
// print error message and continue if there are multiple packages to annotate
fmt.Fprintf(w, "%s in package %q\n", err.Error(), pkgPath)
}
} else {
fmt.Fprintf(w, "added annotations in package %q\n", pkgPath)
}
return nil
} }
func (r *AnnotateRunner) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { func (r *AnnotateRunner) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {

View File

@@ -12,7 +12,9 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/kyaml/copyutil"
"sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/openapi"
) )
func TestAnnotateCommand(t *testing.T) { func TestAnnotateCommand(t *testing.T) {
@@ -486,3 +488,71 @@ spec:
replicas: 3 replicas: 3
` `
) )
func TestAnnotateSubPackages(t *testing.T) {
var tests = []struct {
name string
dataset string
packagePath string
args []string
expected string
}{
{
name: "annotate-recurse-subpackages",
dataset: "dataset-without-setters",
args: []string{"--kv", "foo=bar", "-R"},
expected: `
added annotations in package "${baseDir}/mysql"
added annotations in package "${baseDir}/mysql/storage"
`,
},
{
name: "annotate-top-level-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
packagePath: "mysql",
args: []string{"--kv", "foo=bar"},
expected: `added annotations in package "${baseDir}/mysql"`,
},
{
name: "annotate-nested-pkg-no-recurse-subpackages",
dataset: "dataset-without-setters",
packagePath: "mysql/storage",
args: []string{"--kv", "foo=bar"},
expected: `added annotations in package "${baseDir}/mysql/storage"`,
},
}
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
// reset the openAPI afterward
openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI()
sourceDir := filepath.Join("test", "testdata", test.dataset)
baseDir, err := ioutil.TempDir("", "")
if !assert.NoError(t, err) {
t.FailNow()
}
copyutil.CopyDir(sourceDir, baseDir)
defer os.RemoveAll(baseDir)
runner := NewAnnotateRunner("")
actual := &bytes.Buffer{}
runner.Command.SetOut(actual)
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
err = runner.Command.Execute()
if !assert.NoError(t, err) {
t.FailNow()
}
// normalize path format for windows
actualNormalized := strings.Replace(
strings.Replace(actual.String(), "\\", "/", -1),
"//", "/", -1)
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
if !assert.Equal(t, strings.TrimSpace(expectedNormalized), strings.TrimSpace(actualNormalized)) {
t.FailNow()
}
})
}
}

View File

@@ -4,11 +4,14 @@
package commands package commands
import ( import (
"fmt"
"io"
"path/filepath"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext" "sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands" "sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
"sigs.k8s.io/kustomize/kyaml/fieldmeta" "sigs.k8s.io/kustomize/kyaml/fieldmeta"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil" "sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
) )
@@ -24,6 +27,8 @@ func NewDeleteSetterRunner(parent string) *DeleteSetterRunner {
PreRunE: r.preRunE, PreRunE: r.preRunE,
RunE: r.runE, RunE: r.runE,
} }
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", false,
"deletes setter recursively in all the nested subpackages")
fixDocs(parent, c) fixDocs(parent, c)
r.Command = c r.Command = c
@@ -35,9 +40,10 @@ func DeleteSetterCommand(parent string) *cobra.Command {
} }
type DeleteSetterRunner struct { type DeleteSetterRunner struct {
Command *cobra.Command Command *cobra.Command
DeleteSetter settersutil.DeleterCreator DeleteSetter settersutil.DeleterCreator
OpenAPIFile string OpenAPIFile string
RecurseSubPackages bool
} }
func (r *DeleteSetterRunner) preRunE(c *cobra.Command, args []string) error { func (r *DeleteSetterRunner) preRunE(c *cobra.Command, args []string) error {
@@ -50,17 +56,49 @@ func (r *DeleteSetterRunner) preRunE(c *cobra.Command, args []string) error {
return err return err
} }
if err := openapi.AddSchemaFromFile(r.OpenAPIFile); err != nil {
return err
}
return nil return nil
} }
func (r *DeleteSetterRunner) runE(c *cobra.Command, args []string) error { func (r *DeleteSetterRunner) runE(c *cobra.Command, args []string) error {
return handleError(c, r.delete(c, args)) e := executeCmdOnPkgs{
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
}
err := e.execute()
if err != nil {
return handleError(c, err)
}
return nil
} }
func (r *DeleteSetterRunner) delete(c *cobra.Command, args []string) error { func (r *DeleteSetterRunner) executeCmd(w io.Writer, pkgPath string) error {
return r.DeleteSetter.Delete(r.OpenAPIFile, args[0]) openAPIFileName, err := ext.OpenAPIFileName()
if err != nil {
return err
}
r.DeleteSetter = settersutil.DeleterCreator{
Name: r.DeleteSetter.Name,
DefinitionPrefix: fieldmeta.SetterDefinitionPrefix,
RecurseSubPackages: r.RecurseSubPackages,
OpenAPIFileName: openAPIFileName,
OpenAPIPath: filepath.Join(pkgPath, openAPIFileName),
ResourcesPath: pkgPath,
}
err = r.DeleteSetter.Delete()
if err != nil {
// return err if RecurseSubPackages is false
if !r.DeleteSetter.RecurseSubPackages {
return err
} else {
// print error message and continue if RecurseSubPackages is true
fmt.Fprintf(w, "%s in package %q\n\n", err.Error(), pkgPath)
}
} else {
fmt.Fprintf(w, "deleted setter %q in package %q\n\n", r.DeleteSetter.Name, pkgPath)
}
return nil
} }

View File

@@ -7,12 +7,13 @@ import (
"bytes" "bytes"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath"
"strings" "strings"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/commands" "sigs.k8s.io/kustomize/cmd/config/internal/commands"
"sigs.k8s.io/kustomize/kyaml/copyutil"
"sigs.k8s.io/kustomize/kyaml/openapi" "sigs.k8s.io/kustomize/kyaml/openapi"
) )
@@ -52,6 +53,7 @@ openAPI:
value: "3" value: "3"
setBy: me setBy: me
`, `,
out: `deleted setter "replicas-setter" in package "${baseDir}"`,
expectedOpenAPI: ` expectedOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -95,6 +97,7 @@ openAPI:
name: image name: image
value: nginx value: nginx
`, `,
out: `deleted setter "replicas-setter" in package "${baseDir}"`,
expectedOpenAPI: ` expectedOpenAPI: `
apiVersion: v1alpha1 apiVersion: v1alpha1
kind: Example kind: Example
@@ -158,6 +161,7 @@ spec:
- "b" - "b"
- "c" - "c"
`, `,
out: `deleted setter "list" in package "${baseDir}"`,
expectedResources: ` expectedResources: `
apiVersion: example.com/v1beta1 apiVersion: example.com/v1beta1
kind: Example1 kind: Example1
@@ -226,7 +230,7 @@ metadata:
spec: spec:
replicas: 3 # {"$openapi" : "replicas-setter"} replicas: 3 # {"$openapi" : "replicas-setter"}
`, `,
err: `setter with name image does not exist`, err: `setter "image" does not exist`,
}, },
{ {
name: "delete setter used in substitution error", name: "delete setter used in substitution error",
@@ -287,7 +291,7 @@ openAPI:
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
`, `,
err: `setter is used in substitution image, please delete the parent substitution first`, err: `setter "image-name" is used in substitution "image", please delete the parent substitution first`,
}, },
} }
for i := range tests { for i := range tests {
@@ -297,24 +301,18 @@ kind: Deployment
openapi.ResetOpenAPI() openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI() defer openapi.ResetOpenAPI()
f, err := ioutil.TempFile("", "k8s-cli-") baseDir, err := ioutil.TempDir("", "")
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
defer os.Remove(f.Name()) defer os.RemoveAll(baseDir)
f := filepath.Join(baseDir, "Krmfile")
err = ioutil.WriteFile(f.Name(), []byte(test.inputOpenAPI), 0600) err = ioutil.WriteFile(f, []byte(test.inputOpenAPI), 0600)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
old := ext.GetOpenAPIFile r, err := ioutil.TempFile(baseDir, "k8s-cli-*.yaml")
defer func() { ext.GetOpenAPIFile = old }()
ext.GetOpenAPIFile = func(args []string) (s string, err error) {
return f.Name(), nil
}
r, err := ioutil.TempFile("", "k8s-cli-*.yaml")
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
@@ -327,21 +325,29 @@ kind: Deployment
runner := commands.NewDeleteSetterRunner("") runner := commands.NewDeleteSetterRunner("")
out := &bytes.Buffer{} out := &bytes.Buffer{}
runner.Command.SetOut(out) runner.Command.SetOut(out)
runner.Command.SetArgs(append([]string{r.Name()}, test.args...)) runner.Command.SetArgs(append([]string{baseDir}, test.args...))
err = runner.Command.Execute() err = runner.Command.Execute()
if test.err != "" { if test.err != "" {
if !assert.NotNil(t, err) { if !assert.NotNil(t, err) {
t.FailNow() t.FailNow()
} else {
assert.Equal(t, err.Error(), test.err)
return
} }
assert.Equal(t, test.err, err.Error())
return
} }
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
if !assert.Equal(t, test.out, out.String()) { // normalize path format for windows
actualNorm := strings.Replace(
strings.Replace(out.String(), "\\", "/", -1),
"//", "/", -1)
expectedOut := strings.Replace(test.out, "${baseDir}", baseDir, -1)
expectedNormalized := strings.Replace(expectedOut, "\\", "/", -1)
if !assert.Equal(t, expectedNormalized, strings.TrimSpace(actualNorm)) {
t.FailNow() t.FailNow()
} }
@@ -355,7 +361,7 @@ kind: Deployment
t.FailNow() t.FailNow()
} }
actualOpenAPI, err := ioutil.ReadFile(f.Name()) actualOpenAPI, err := ioutil.ReadFile(f)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
@@ -367,3 +373,74 @@ kind: Deployment
}) })
} }
} }
func TestDeleteSetterSubPackages(t *testing.T) {
var tests = []struct {
name string
dataset string
packagePath string
args []string
expected string
}{
{
name: "delete-setter-recurse-subpackages",
dataset: "dataset-with-setters",
args: []string{"namespace", "-R"},
expected: `
deleted setter "namespace" in package "${baseDir}/mysql"
setter "namespace" does not exist in package "${baseDir}/mysql/nosetters"
deleted setter "namespace" in package "${baseDir}/mysql/storage"
`,
},
{
name: "delete-setter-top-level-pkg-no-recurse-subpackages",
dataset: "dataset-with-setters",
packagePath: "mysql",
args: []string{"namespace"},
expected: `deleted setter "namespace" in package "${baseDir}/mysql"`,
},
{
name: "delete-setter-nested-pkg-no-recurse-subpackages",
dataset: "dataset-with-setters",
packagePath: "mysql/storage",
args: []string{"namespace"},
expected: `deleted setter "namespace" in package "${baseDir}/mysql/storage"`,
},
}
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
// reset the openAPI afterward
openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI()
sourceDir := filepath.Join("test", "testdata", test.dataset)
baseDir, err := ioutil.TempDir("", "")
if !assert.NoError(t, err) {
t.FailNow()
}
copyutil.CopyDir(sourceDir, baseDir)
//defer os.RemoveAll(baseDir)
runner := commands.NewDeleteSetterRunner("")
actual := &bytes.Buffer{}
runner.Command.SetOut(actual)
runner.Command.SetArgs(append([]string{filepath.Join(baseDir, test.packagePath)}, test.args...))
err = runner.Command.Execute()
if !assert.NoError(t, err) {
t.FailNow()
}
// normalize path format for windows
actualNormalized := strings.Replace(
strings.Replace(actual.String(), "\\", "/", -1),
"//", "/", -1)
expected := strings.Replace(test.expected, "${baseDir}", baseDir, -1)
expectedNormalized := strings.Replace(expected, "\\", "/", -1)
if !assert.Equal(t, strings.TrimSpace(expectedNormalized), strings.TrimSpace(actualNormalized)) {
t.FailNow()
}
})
}
}

View File

@@ -4,6 +4,10 @@
package commands package commands
import ( import (
"fmt"
"io"
"path/filepath"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"sigs.k8s.io/kustomize/cmd/config/ext" "sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/kyaml/fieldmeta" "sigs.k8s.io/kustomize/kyaml/fieldmeta"
@@ -20,6 +24,8 @@ func NewDeleteSubstitutionRunner(parent string) *DeleteSubstitutionRunner {
PreRunE: r.preRunE, PreRunE: r.preRunE,
RunE: r.runE, RunE: r.runE,
} }
c.Flags().BoolVarP(&r.RecurseSubPackages, "recurse-subpackages", "R", false,
"deletes substitution recursively in all the nested subpackages")
fixDocs(parent, c) fixDocs(parent, c)
r.Command = c r.Command = c
@@ -34,6 +40,7 @@ type DeleteSubstitutionRunner struct {
Command *cobra.Command Command *cobra.Command
DeleteSubstitution settersutil.DeleterCreator DeleteSubstitution settersutil.DeleterCreator
OpenAPIFile string OpenAPIFile string
RecurseSubPackages bool
} }
func (r *DeleteSubstitutionRunner) preRunE(c *cobra.Command, args []string) error { func (r *DeleteSubstitutionRunner) preRunE(c *cobra.Command, args []string) error {
@@ -54,9 +61,45 @@ func (r *DeleteSubstitutionRunner) preRunE(c *cobra.Command, args []string) erro
} }
func (r *DeleteSubstitutionRunner) runE(c *cobra.Command, args []string) error { func (r *DeleteSubstitutionRunner) runE(c *cobra.Command, args []string) error {
return handleError(c, r.delete(c, args)) e := executeCmdOnPkgs{
needOpenAPI: true,
writer: c.OutOrStdout(),
rootPkgPath: args[0],
recurseSubPackages: r.RecurseSubPackages,
cmdRunner: r,
}
err := e.execute()
if err != nil {
return handleError(c, err)
}
return nil
} }
func (r *DeleteSubstitutionRunner) delete(c *cobra.Command, args []string) error { func (r *DeleteSubstitutionRunner) executeCmd(w io.Writer, pkgPath string) error {
return r.DeleteSubstitution.Delete(r.OpenAPIFile, args[0]) openAPIFileName, err := ext.OpenAPIFileName()
if err != nil {
return err
}
r.DeleteSubstitution = settersutil.DeleterCreator{
Name: r.DeleteSubstitution.Name,
DefinitionPrefix: fieldmeta.SubstitutionDefinitionPrefix,
RecurseSubPackages: r.RecurseSubPackages,
OpenAPIFileName: openAPIFileName,
OpenAPIPath: filepath.Join(pkgPath, openAPIFileName),
ResourcesPath: pkgPath,
}
err = r.DeleteSubstitution.Delete()
if err != nil {
// return err if RecurseSubPackages is false
if !r.DeleteSubstitution.RecurseSubPackages {
return err
} else {
// print error message and continue if RecurseSubPackages is true
fmt.Fprintf(w, "%s in package %q\n\n", err.Error(), pkgPath)
}
} else {
fmt.Fprintf(w, "deleted substitution %q in package %q\n\n", r.DeleteSubstitution.Name, pkgPath)
}
return nil
} }

View File

@@ -7,11 +7,11 @@ import (
"bytes" "bytes"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath"
"strings" "strings"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/cmd/config/ext"
"sigs.k8s.io/kustomize/cmd/config/internal/commands" "sigs.k8s.io/kustomize/cmd/config/internal/commands"
"sigs.k8s.io/kustomize/kyaml/openapi" "sigs.k8s.io/kustomize/kyaml/openapi"
) )
@@ -79,6 +79,7 @@ spec:
- name: sidecar - name: sidecar
image: nginx:1.7.9 # {"$ref":"#/definitions/io.k8s.cli.substitutions.my.image"} image: nginx:1.7.9 # {"$ref":"#/definitions/io.k8s.cli.substitutions.my.image"}
`, `,
out: `deleted substitution "my.image" in package "${baseDir}"`,
expectedResources: ` expectedResources: `
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
@@ -169,6 +170,7 @@ spec:
- name: sidecar - name: sidecar
image: nginx:1.7.9 # {"$openapi":"my-image-sub"} image: nginx:1.7.9 # {"$openapi":"my-image-sub"}
`, `,
out: `deleted substitution "my-image-sub" in package "${baseDir}"`,
expectedResources: ` expectedResources: `
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
@@ -297,7 +299,7 @@ openAPI:
value: "3" value: "3"
setBy: me setBy: me
`, `,
err: "substitution with name my-image-sub-not-present does not exist", err: `substitution "my-image-sub-not-present" does not exist`,
}, },
{ {
@@ -415,7 +417,7 @@ spec:
- name: sidecar - name: sidecar
image: nginx::1.7.9 # {"$openapi":"my-image-subst"} image: nginx::1.7.9 # {"$openapi":"my-image-subst"}
`, `,
err: "substitution is used in substitution my-nested-subst, please delete the parent substitution first", err: `substitution "my-image-subst" is used in substitution "my-nested-subst", please delete the parent substitution first`,
}, },
} }
for i := range tests { for i := range tests {
@@ -425,24 +427,18 @@ spec:
openapi.ResetOpenAPI() openapi.ResetOpenAPI()
defer openapi.ResetOpenAPI() defer openapi.ResetOpenAPI()
f, err := ioutil.TempFile("", "k8s-cli-") baseDir, err := ioutil.TempDir("", "")
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
defer os.Remove(f.Name()) defer os.RemoveAll(baseDir)
f := filepath.Join(baseDir, "Krmfile")
err = ioutil.WriteFile(f.Name(), []byte(test.inputOpenAPI), 0600) err = ioutil.WriteFile(f, []byte(test.inputOpenAPI), 0600)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
old := ext.GetOpenAPIFile r, err := ioutil.TempFile(baseDir, "k8s-cli-*.yaml")
defer func() { ext.GetOpenAPIFile = old }()
ext.GetOpenAPIFile = func(args []string) (s string, err error) {
return f.Name(), nil
}
r, err := ioutil.TempFile("", "k8s-cli-*.yaml")
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
@@ -455,21 +451,38 @@ spec:
runner := commands.NewDeleteSubstitutionRunner("") runner := commands.NewDeleteSubstitutionRunner("")
out := &bytes.Buffer{} out := &bytes.Buffer{}
runner.Command.SetOut(out) runner.Command.SetOut(out)
runner.Command.SetArgs(append([]string{r.Name()}, test.args...)) runner.Command.SetArgs(append([]string{baseDir}, test.args...))
err = runner.Command.Execute() err = runner.Command.Execute()
if test.err != "" { if test.err != "" {
if !assert.NotNil(t, err) { if !assert.NotNil(t, err) {
t.FailNow() t.FailNow()
} else {
assert.Equal(t, err.Error(), test.err)
return
} }
assert.Equal(t, test.err, err.Error())
return
} }
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
if !assert.Equal(t, test.out, out.String()) { // normalize path format for windows
actualNorm := strings.Replace(
strings.Replace(out.String(), "\\", "/", -1),
"//", "/", -1)
expectedOut := strings.Replace(test.out, "${baseDir}", baseDir, -1)
expectedNorm := strings.Replace(expectedOut, "\\", "/", -1)
if !assert.Equal(t, expectedNorm, strings.TrimSpace(actualNorm)) {
t.FailNow()
}
actualOpenAPI, err := ioutil.ReadFile(f)
if !assert.NoError(t, err) {
t.FailNow()
}
if !assert.Equal(t,
strings.TrimSpace(test.expectedOpenAPI),
strings.TrimSpace(string(actualOpenAPI))) {
t.FailNow() t.FailNow()
} }
@@ -480,18 +493,9 @@ spec:
if !assert.Equal(t, if !assert.Equal(t,
strings.TrimSpace(test.expectedResources), strings.TrimSpace(test.expectedResources),
strings.TrimSpace(string(actualResources))) { strings.TrimSpace(string(actualResources))) {
return t.FailNow()
} }
actualOpenAPI, err := ioutil.ReadFile(f.Name())
if !assert.NoError(t, err) {
t.FailNow()
}
if !assert.Equal(t,
strings.TrimSpace(test.expectedOpenAPI),
strings.TrimSpace(string(actualOpenAPI))) {
t.FailNow()
}
}) })
} }
} }

View File

@@ -135,18 +135,18 @@ func (dd DeleterDefinition) Filter(object *yaml.RNode) (*yaml.RNode, error) {
} }
definitions, err := object.Pipe(yaml.Lookup(openapi.SupplementaryOpenAPIFieldName, "definitions")) definitions, err := object.Pipe(yaml.Lookup(openapi.SupplementaryOpenAPIFieldName, "definitions"))
if err != nil || definitions == nil { if err != nil {
return nil, err return nil, err
} }
// return error if the setter to be deleted doesn't exist // return error if the setter to be deleted doesn't exist
if definitions.Field(key) == nil { if definitions == nil || definitions.Field(key) == nil {
return nil, errors.Errorf("%s with name %s does not exist", defType, dd.Name) return nil, errors.Errorf("%s %q does not exist", defType, dd.Name)
} }
subst := SubstReferringDefinition(definitions, key) subst := SubstReferringDefinition(definitions, key)
if subst != "" { if subst != "" {
return nil, errors.Errorf("%s is used in substitution %s, please delete the parent substitution first", defType, subst) return nil, errors.Errorf("%s %q is used in substitution %q, please delete the parent substitution first", defType, dd.Name, subst)
} }
_, err = definitions.Pipe(yaml.FieldClearer{Name: key}) _, err = definitions.Pipe(yaml.FieldClearer{Name: key})

View File

@@ -75,8 +75,10 @@ func TestDeleterCreator_Delete(t *testing.T) {
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
dc.OpenAPIPath = openAPI.Name()
dc.ResourcesPath = resource.Name()
err = dc.Delete(openAPI.Name(), resource.Name()) err = dc.Delete()
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }

View File

@@ -17,24 +17,34 @@ type DeleterCreator struct {
// DefinitionPrefix is the prefix of the OpenAPI definition type // DefinitionPrefix is the prefix of the OpenAPI definition type
DefinitionPrefix string DefinitionPrefix string
RecurseSubPackages bool
OpenAPIFileName string
// Path to openAPI file
OpenAPIPath string
// Path to resources folder
ResourcesPath string
} }
func (d DeleterCreator) Delete(openAPIPath, resourcesPath string) error { func (d DeleterCreator) Delete() error {
dd := setters2.DeleterDefinition{ dd := setters2.DeleterDefinition{
Name: d.Name, Name: d.Name,
DefinitionPrefix: d.DefinitionPrefix, DefinitionPrefix: d.DefinitionPrefix,
} }
if err := dd.DeleteFromFile(openAPIPath); err != nil { if err := dd.DeleteFromFile(d.OpenAPIPath); err != nil {
return err return err
} }
// Load the updated definitions // Load the updated definitions
if err := openapi.AddSchemaFromFile(openAPIPath); err != nil { if err := openapi.AddSchemaFromFile(d.OpenAPIPath); err != nil {
return err return err
} }
// Update the resources with the deleter reference // Update the resources with the deleter reference
inout := &kio.LocalPackageReadWriter{PackagePath: resourcesPath} inout := &kio.LocalPackageReadWriter{PackagePath: d.ResourcesPath, PackageFileName: d.OpenAPIFileName}
return kio.Pipeline{ return kio.Pipeline{
Inputs: []kio.Reader{inout}, Inputs: []kio.Reader{inout},
Filters: []kio.Filter{kio.FilterAll( Filters: []kio.Filter{kio.FilterAll(