Defer openAPI cleanup

This commit is contained in:
Phani Teja Marupaka
2020-11-02 12:07:32 -08:00
parent 49094cf999
commit ec2cc2d421
13 changed files with 110 additions and 92 deletions

View File

@@ -60,37 +60,34 @@ func (e ExecuteCmdOnPkgs) Execute() error {
} }
for i := range pkgsPaths { for i := range pkgsPaths {
pkgPath := pkgsPaths[i] err := e.processPkg(pkgsPaths[i])
// Add schema present in openAPI file for current package
if e.NeedOpenAPI {
if err := openapi.AddSchemaFromFile(filepath.Join(pkgPath, ext.KRMFileName())); err != nil {
return err
}
}
if !e.SkipPkgPathPrint {
fmt.Fprintf(e.Writer, "%s/\n", pkgPath)
}
err := e.CmdRunner.ExecuteCmd(e.Writer, pkgPath)
if err != nil { if err != nil {
return err return err
} }
if i != len(pkgsPaths)-1 { if i != len(pkgsPaths)-1 {
fmt.Fprint(e.Writer, "\n") fmt.Fprint(e.Writer, "\n")
} }
// Delete schema present in openAPI file for current package
if e.NeedOpenAPI {
if err := openapi.DeleteSchemaInFile(filepath.Join(pkgPath, ext.KRMFileName())); err != nil {
return err
}
}
} }
return nil return nil
} }
func (e ExecuteCmdOnPkgs) processPkg(pkgPath string) error {
// Add schema present in openAPI file for current package
if e.NeedOpenAPI {
clean, err := openapi.AddSchemaFromFile(filepath.Join(pkgPath, ext.KRMFileName()))
if err != nil {
return err
}
defer clean()
}
if !e.SkipPkgPathPrint {
fmt.Fprintf(e.Writer, "%s/\n", pkgPath)
}
return e.CmdRunner.ExecuteCmd(e.Writer, pkgPath)
}
// ParseFieldPath parse a flag value into a field path // ParseFieldPath parse a flag value into a field path
func ParseFieldPath(path string) ([]string, error) { func ParseFieldPath(path string) ([]string, error) {
// fixup '\.' so we don't split on it // fixup '\.' so we don't split on it

View File

@@ -65,28 +65,54 @@ const SupplementaryOpenAPIFieldName = "openAPI"
const Definitions = "definitions" const Definitions = "definitions"
// AddSchemaFromFile reads the file at path and parses the OpenAPI definitions // AddSchemaFromFile reads the file at path and parses the OpenAPI definitions
// from the field "openAPI" // from the field "openAPI", also returns a function to clean the added definitions
func AddSchemaFromFile(path string) error { // The returned clean function is a no-op on error, or else it's a function
return AddSchemaFromFileUsingField(path, SupplementaryOpenAPIFieldName) // that the caller should use to remove the added openAPI definitions from
} // global schema
func AddSchemaFromFile(path string) (func(), error) {
// DeleteSchemaInFile reads the file at path and removes all the openAPI definitions object, err := parseOpenAPI(path)
// present in file from global schema
func DeleteSchemaInFile(openAPIPath string) error {
fields, err := DefinitionRefs(openAPIPath)
if err != nil { if err != nil {
return err return func() {}, err
} }
for _, field := range fields { defs, err := definitionRefsFromRNode(object)
delete(globalSchema.schema.Definitions, field) if err != nil {
return func() {}, err
} }
return nil
clean := func() {
for _, def := range defs {
delete(globalSchema.schema.Definitions, def)
}
}
return clean, addSchemaUsingField(object, SupplementaryOpenAPIFieldName)
} }
// DefinitionRefs returns the list of openAPI definition references present in the // DefinitionRefs returns the list of openAPI definition references present in the
// input openAPIPath // input openAPIPath
func DefinitionRefs(openAPIPath string) ([]string, error) { func DefinitionRefs(openAPIPath string) ([]string, error) {
object, err := parseOpenAPI(openAPIPath)
if err != nil {
return nil, err
}
return definitionRefsFromRNode(object)
}
// definitionRefsFromRNode returns the list of openAPI definitions keys from input
// yaml RNode
func definitionRefsFromRNode(object *yaml.RNode) ([]string, error) {
definitions, err := object.Pipe(yaml.Lookup(SupplementaryOpenAPIFieldName, Definitions))
if definitions == nil {
return nil, err
}
if err != nil {
return nil, err
}
return definitions.Fields()
}
// parseOpenAPI reads openAPIPath yaml and converts it to RNode
func parseOpenAPI(openAPIPath string) (*yaml.RNode, error) {
b, err := ioutil.ReadFile(openAPIPath) b, err := ioutil.ReadFile(openAPIPath)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -96,44 +122,23 @@ func DefinitionRefs(openAPIPath string) ([]string, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return object, nil
definitions, err := object.Pipe(yaml.Lookup(SupplementaryOpenAPIFieldName, Definitions))
if definitions == nil {
return nil, err
}
if err != nil {
return nil, err
}
return definitions.Fields()
} }
// AddSchemaFromFileUsingField reads the file at path and parses the OpenAPI definitions // addSchemaUsingField parses the OpenAPI definitions from the specified field.
// from the specified field. If field is the empty string, use the whole document as // If field is the empty string, use the whole document as OpenAPI.
// OpenAPI. func addSchemaUsingField(object *yaml.RNode, field string) error {
func AddSchemaFromFileUsingField(path, field string) error {
b, err := ioutil.ReadFile(path)
if err != nil {
return err
}
// parse the yaml file (json is a subset of yaml, so will also parse)
y, err := yaml.Parse(string(b))
if err != nil {
return err
}
if field != "" { if field != "" {
// get the field containing the openAPI // get the field containing the openAPI
m := y.Field(field) m := object.Field(field)
if m.IsNilOrEmpty() { if m.IsNilOrEmpty() {
// doesn't contain openAPI definitions // doesn't contain openAPI definitions
return nil return nil
} }
y = m.Value object = m.Value
} }
oAPI, err := y.String() oAPI, err := object.String()
if err != nil { if err != nil {
return err return err
} }

View File

@@ -143,10 +143,11 @@ openAPI:
t.FailNow() t.FailNow()
} }
err = AddSchemaFromFile(f.Name()) clean, err := AddSchemaFromFile(f.Name())
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
defer clean()
s, err := GetSchema(`{"$ref": "#/definitions/io.k8s.cli.setters.image-name"}`) s, err := GetSchema(`{"$ref": "#/definitions/io.k8s.cli.setters.image-name"}`)
@@ -179,7 +180,7 @@ openAPI:
t.FailNow() t.FailNow()
} }
err = AddSchemaFromFile(f.Name()) clean, err := AddSchemaFromFile(f.Name())
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
@@ -195,10 +196,7 @@ openAPI:
assert.Equal(t, `map[x-k8s-cli:map[setter:map[name:image-name value:nginx]]]`, assert.Equal(t, `map[x-k8s-cli:map[setter:map[name:image-name value:nginx]]]`,
fmt.Sprintf("%v", s.Schema.Extensions)) fmt.Sprintf("%v", s.Schema.Extensions))
err = DeleteSchemaInFile(f.Name()) clean()
if !assert.NoError(t, err) {
t.FailNow()
}
_, err = GetSchema(`{"$ref": "#/definitions/io.k8s.cli.setters.image-name"}`) _, err = GetSchema(`{"$ref": "#/definitions/io.k8s.cli.setters.image-name"}`)
@@ -225,15 +223,11 @@ openAPI:
t.FailNow() t.FailNow()
} }
err = AddSchemaFromFile(f.Name()) clean, err := AddSchemaFromFile(f.Name())
if !assert.NoError(t, err) {
t.FailNow()
}
err = DeleteSchemaInFile(f.Name())
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
defer clean()
} }
func TestPopulateDefsInOpenAPI_Substitution(t *testing.T) { func TestPopulateDefsInOpenAPI_Substitution(t *testing.T) {
@@ -271,9 +265,11 @@ openAPI:
t.FailNow() t.FailNow()
} }
if !assert.NoError(t, AddSchemaFromFile(f.Name())) { clean, err := AddSchemaFromFile(f.Name())
if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
defer clean()
s, err := GetSchema(`{"$ref": "#/definitions/io.k8s.cli.substitutions.image"}`) s, err := GetSchema(`{"$ref": "#/definitions/io.k8s.cli.substitutions.image"}`)
@@ -305,9 +301,11 @@ kind: Example
t.FailNow() t.FailNow()
} }
if !assert.NoError(t, AddSchemaFromFile(f.Name())) { clean, err := AddSchemaFromFile(f.Name())
if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
defer clean()
if !assert.Equal(t, len(globalSchema.schema.Definitions), 0) { if !assert.Equal(t, len(globalSchema.schema.Definitions), 0) {
t.FailNow() t.FailNow()

View File

@@ -342,7 +342,7 @@ openAPI:
func TestAddUpdateSubstitution(t *testing.T) { func TestAddUpdateSubstitution(t *testing.T) {
path := filepath.Join(os.TempDir(), "resourcefile") path := filepath.Join(os.TempDir(), "resourcefile")
//write initial resourcefile to temp path // write initial resourcefile to temp path
err := ioutil.WriteFile(path, []byte(resourcefile), 0666) err := ioutil.WriteFile(path, []byte(resourcefile), 0666)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
@@ -360,7 +360,7 @@ func TestAddUpdateSubstitution(t *testing.T) {
values := []Value{value1, value2} values := []Value{value1, value2}
//add a setter definition // add a setter definition
subd := SubstitutionDefinition{ subd := SubstitutionDefinition{
Name: "image", Name: "image",
Pattern: "IMAGE_NAME:IMAGE_TAG", Pattern: "IMAGE_NAME:IMAGE_TAG",

View File

@@ -42,13 +42,13 @@ openAPI:
func TestDelete_Filter2(t *testing.T) { func TestDelete_Filter2(t *testing.T) {
path := filepath.Join(os.TempDir(), "resourcefile2") path := filepath.Join(os.TempDir(), "resourcefile2")
//write initial resourcefile to temp path // write initial resourcefile to temp path
err := ioutil.WriteFile(path, []byte(resourcefile2), 0666) err := ioutil.WriteFile(path, []byte(resourcefile2), 0666)
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
//add a deleter definition // add a deleter definition
dd := DeleterDefinition{ dd := DeleterDefinition{
Name: "image", Name: "image",
DefinitionPrefix: fieldmeta.SetterDefinitionPrefix, DefinitionPrefix: fieldmeta.SetterDefinitionPrefix,

View File

@@ -29,9 +29,11 @@ type List struct {
// ListSetters initializes l.Setters with the setters from the OpenAPI definitions in the file // ListSetters initializes l.Setters with the setters from the OpenAPI definitions in the file
func (l *List) ListSetters(openAPIPath, resourcePath string) error { func (l *List) ListSetters(openAPIPath, resourcePath string) error {
if err := openapi.AddSchemaFromFile(openAPIPath); err != nil { clean, err := openapi.AddSchemaFromFile(openAPIPath)
if err != nil {
return err return err
} }
defer clean()
y, err := yaml.ReadFile(openAPIPath) y, err := yaml.ReadFile(openAPIPath)
if err != nil { if err != nil {
return err return err
@@ -41,9 +43,11 @@ func (l *List) ListSetters(openAPIPath, resourcePath string) error {
// ListSubst initializes l.Substitutions with the substitutions from the OpenAPI definitions in the file // ListSubst initializes l.Substitutions with the substitutions from the OpenAPI definitions in the file
func (l *List) ListSubst(openAPIPath string) error { func (l *List) ListSubst(openAPIPath string) error {
if err := openapi.AddSchemaFromFile(openAPIPath); err != nil { clean, err := openapi.AddSchemaFromFile(openAPIPath)
if err != nil {
return err return err
} }
defer clean()
y, err := yaml.ReadFile(openAPIPath) y, err := yaml.ReadFile(openAPIPath)
if err != nil { if err != nil {
return err return err

View File

@@ -71,10 +71,11 @@ func TestDeleterCreator_Delete(t *testing.T) {
DefinitionPrefix: fieldmeta.SetterDefinitionPrefix, DefinitionPrefix: fieldmeta.SetterDefinitionPrefix,
} }
err = openapi.AddSchemaFromFile(openAPI.Name()) clean, err := openapi.AddSchemaFromFile(openAPI.Name())
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
defer clean()
dc.OpenAPIPath = openAPI.Name() dc.OpenAPIPath = openAPI.Name()
dc.ResourcesPath = resource.Name() dc.ResourcesPath = resource.Name()

View File

@@ -39,9 +39,11 @@ func (d DeleterCreator) Delete() error {
} }
// Load the updated definitions // Load the updated definitions
if err := openapi.AddSchemaFromFile(d.OpenAPIPath); err != nil { clean, err := openapi.AddSchemaFromFile(d.OpenAPIPath)
if err != nil {
return err return err
} }
defer clean()
// Update the resources with the deleter reference // Update the resources with the deleter reference
inout := &kio.LocalPackageReadWriter{PackagePath: d.ResourcesPath, PackageFileName: d.OpenAPIFileName} inout := &kio.LocalPackageReadWriter{PackagePath: d.ResourcesPath, PackageFileName: d.OpenAPIFileName}

View File

@@ -79,9 +79,11 @@ func (fs FieldSetter) Set() (int, error) {
} }
// Load the updated definitions // Load the updated definitions
if err := openapi.AddSchemaFromFile(fs.OpenAPIPath); err != nil { clean, err := openapi.AddSchemaFromFile(fs.OpenAPIPath)
if err != nil {
return 0, err return 0, err
} }
defer clean()
// Update the resources with the new value // Update the resources with the new value
// Set NoDeleteFiles to true as SetAll will return only the nodes of files which should be updated and // Set NoDeleteFiles to true as SetAll will return only the nodes of files which should be updated and
@@ -108,9 +110,11 @@ func (fs FieldSetter) Set() (int, error) {
// If syncOpenAPI is true, the openAPI files in destination directories are also // If syncOpenAPI is true, the openAPI files in destination directories are also
// updated with the setter values in the input openAPI file // updated with the setter values in the input openAPI file
func SetAllSetterDefinitions(syncOpenAPI bool, openAPIPath string, dirs ...string) error { func SetAllSetterDefinitions(syncOpenAPI bool, openAPIPath string, dirs ...string) error {
if err := openapi.AddSchemaFromFile(openAPIPath); err != nil { clean, err := openapi.AddSchemaFromFile(openAPIPath)
if err != nil {
return err return err
} }
defer clean()
for _, destDir := range dirs { for _, destDir := range dirs {
if syncOpenAPI { if syncOpenAPI {
openAPIFileName := filepath.Base(openAPIPath) openAPIFileName := filepath.Base(openAPIPath)
@@ -122,7 +126,7 @@ func SetAllSetterDefinitions(syncOpenAPI bool, openAPIPath string, dirs ...strin
rw := &kio.LocalPackageReadWriter{ rw := &kio.LocalPackageReadWriter{
PackagePath: destDir, PackagePath: destDir,
// set output won't include resources from files which // set output won't include resources from files which
//weren't modified. make sure we don't delete them. // weren't modified. make sure we don't delete them.
NoDeleteFiles: true, NoDeleteFiles: true,
} }

View File

@@ -103,9 +103,11 @@ func (c SetterCreator) Create() error {
} }
// Load the updated definitions // Load the updated definitions
if err := openapi.AddSchemaFromFile(c.OpenAPIPath); err != nil { clean, err := openapi.AddSchemaFromFile(c.OpenAPIPath)
if err != nil {
return err return err
} }
defer clean()
// if the setter is of array type write the derived list values back to // if the setter is of array type write the derived list values back to
// openAPI definitions // openAPI definitions
if len(a.ListValues) > 0 { if len(a.ListValues) > 0 {

View File

@@ -93,9 +93,11 @@ func (c SubstitutionCreator) Create() error {
} }
// Load the updated definitions // Load the updated definitions
if err := openapi.AddSchemaFromFile(c.OpenAPIPath); err != nil { clean, err := openapi.AddSchemaFromFile(c.OpenAPIPath)
if err != nil {
return err return err
} }
defer clean()
visited := sets.String{} visited := sets.String{}
ref, err := spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SubstitutionDefinitionPrefix + c.Name) ref, err := spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SubstitutionDefinitionPrefix + c.Name)
@@ -119,9 +121,11 @@ func (c SubstitutionCreator) Create() error {
} }
// Load the updated definitions after setters are created // Load the updated definitions after setters are created
if err := openapi.AddSchemaFromFile(c.OpenAPIPath); err != nil { clean, err = openapi.AddSchemaFromFile(c.OpenAPIPath)
if err != nil {
return err return err
} }
defer clean()
// revert openAPI file if there are cycles detected in created input substitution // revert openAPI file if there are cycles detected in created input substitution
if err := checkForCycles(ext, visited); err != nil { if err := checkForCycles(ext, visited); err != nil {

View File

@@ -103,7 +103,7 @@ func TestGetValuesForMarkers(t *testing.T) {
} }
} }
} else { } else {
//if expectedError is not nil, check for correctness of error message // if expectedError is not nil, check for correctness of error message
assert.Contains(t, err.Error(), test.expectedError.Error()) assert.Contains(t, err.Error(), test.expectedError.Error())
} }
}) })

View File

@@ -154,7 +154,8 @@ openAPI:
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
err = openapi.AddSchemaFromFile(filepath.Join(dir, "Krmfile")) clean, err := openapi.AddSchemaFromFile(filepath.Join(dir, "Krmfile"))
defer clean()
if err != nil { if err != nil {
// do nothing if openAPI file or schema doesn't exist, CheckRequiredSettersSet() // do nothing if openAPI file or schema doesn't exist, CheckRequiredSettersSet()
// should not throw any error // should not throw any error