Setters with subpackages

This commit is contained in:
Phani Teja Marupaka
2020-08-27 21:22:43 -07:00
parent 0e9428c8b0
commit f432f4d75e
35 changed files with 795 additions and 210 deletions

View File

@@ -367,14 +367,14 @@ func (s SetOpenAPI) Filter(object *yaml.RNode) (*yaml.RNode, error) {
return nil, err
}
if oa == nil {
return nil, errors.Errorf("no setter %s found", s.Name)
return nil, errors.Errorf("setter %q is not found", s.Name)
}
def, err := oa.Pipe(yaml.Lookup("x-k8s-cli", "setter"))
if err != nil {
return nil, err
}
if def == nil {
return nil, errors.Errorf("no setter %s found", s.Name)
return nil, errors.Errorf("setter %q is not found", s.Name)
}
// record the OpenAPI type for the setter

View File

@@ -1271,7 +1271,7 @@ openAPI:
{
name: "error",
setter: "replicas",
err: "no setter replicas found",
err: `setter "replicas" is not found`,
input: `
openAPI:
definitions:

View File

@@ -32,16 +32,20 @@ type FieldSetter struct {
OpenAPIPath string
OpenAPIFileName string
ResourcesPath string
RecurseSubPackages bool
}
func (fs *FieldSetter) Filter(input []*yaml.RNode) ([]*yaml.RNode, error) {
fs.Count, _ = fs.Set(fs.OpenAPIPath, fs.ResourcesPath)
fs.Count, _ = fs.Set()
return nil, nil
}
// Set updates the OpenAPI definitions and resources with the new setter value
func (fs FieldSetter) Set(openAPIPath, resourcesPath string) (int, error) {
func (fs FieldSetter) Set() (int, error) {
// Update the OpenAPI definitions
soa := setters2.SetOpenAPI{
Name: fs.Name,
@@ -55,30 +59,30 @@ func (fs FieldSetter) Set(openAPIPath, resourcesPath string) (int, error) {
// at to get the value and set it to resource files, but if there is error
// after updating openAPI file and while updating resources, the openAPI
// file should be reverted, as set operation failed
stat, err := os.Stat(openAPIPath)
stat, err := os.Stat(fs.OpenAPIPath)
if err != nil {
return 0, err
}
curOpenAPI, err := ioutil.ReadFile(openAPIPath)
curOpenAPI, err := ioutil.ReadFile(fs.OpenAPIPath)
if err != nil {
return 0, err
}
// write the new input value to openAPI file
if err := soa.UpdateFile(openAPIPath); err != nil {
if err := soa.UpdateFile(fs.OpenAPIPath); err != nil {
return 0, err
}
// Load the updated definitions
if err := openapi.AddSchemaFromFile(openAPIPath); err != nil {
if err := openapi.AddSchemaFromFile(fs.OpenAPIPath); err != nil {
return 0, err
}
// 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
// hence, rest of the files should not be deleted
inout := &kio.LocalPackageReadWriter{PackagePath: resourcesPath, NoDeleteFiles: true}
inout := &kio.LocalPackageReadWriter{PackagePath: fs.ResourcesPath, NoDeleteFiles: true, PackageFileName: fs.OpenAPIFileName}
s := &setters2.Set{Name: fs.Name}
err = kio.Pipeline{
Inputs: []kio.Reader{inout},
@@ -88,7 +92,7 @@ func (fs FieldSetter) Set(openAPIPath, resourcesPath string) (int, error) {
// revert openAPI file if set operation fails
if err != nil {
if writeErr := ioutil.WriteFile(openAPIPath, curOpenAPI, stat.Mode().Perm()); writeErr != nil {
if writeErr := ioutil.WriteFile(fs.OpenAPIPath, curOpenAPI, stat.Mode().Perm()); writeErr != nil {
return 0, writeErr
}
}

View File

@@ -47,6 +47,10 @@ type SetterCreator struct {
// the package publisher's intent to make the setter required to be set.
Required bool
RecurseSubPackages bool
OpenAPIFileName string
// Path to openAPI file
OpenAPIPath string
@@ -55,17 +59,21 @@ type SetterCreator struct {
}
func (c *SetterCreator) Filter(input []*yaml.RNode) ([]*yaml.RNode, error) {
return nil, c.Create(c.OpenAPIPath, c.ResourcesPath)
return nil, c.Create()
}
func (c SetterCreator) Create(openAPIPath, resourcesPath string) error {
err := validateSchema(c.Schema)
func (c SetterCreator) Create() error {
err := c.validateSetterInfo()
if err != nil {
return err
}
err = validateSchema(c.Schema)
if err != nil {
return errors.Errorf("invalid schema: %v", err)
}
// Update the resources with the setter reference
inout := &kio.LocalPackageReadWriter{PackagePath: resourcesPath}
inout := &kio.LocalPackageReadWriter{PackagePath: c.ResourcesPath}
a := &setters2.Add{
FieldName: c.FieldName,
FieldValue: c.FieldValue,
@@ -78,7 +86,7 @@ func (c SetterCreator) Create(openAPIPath, resourcesPath string) error {
Outputs: []kio.Writer{inout},
}.Execute()
if a.Count == 0 {
fmt.Printf("setter %s doesn't match any field in resource configs, "+
fmt.Printf("setter %q doesn't match any field in resource configs, "+
"but creating setter definition\n", c.Name)
}
if err != nil {
@@ -90,12 +98,12 @@ func (c SetterCreator) Create(openAPIPath, resourcesPath string) error {
Name: c.Name, Value: c.FieldValue, SetBy: c.SetBy, Description: c.Description,
Type: c.Type, Schema: c.Schema, Required: c.Required,
}
if err := sd.AddToFile(openAPIPath); err != nil {
if err := sd.AddToFile(c.OpenAPIPath); err != nil {
return err
}
// Load the updated definitions
if err := openapi.AddSchemaFromFile(openAPIPath); err != nil {
if err := openapi.AddSchemaFromFile(c.OpenAPIPath); err != nil {
return err
}
// if the setter is of array type write the derived list values back to
@@ -103,7 +111,7 @@ func (c SetterCreator) Create(openAPIPath, resourcesPath string) error {
if len(a.ListValues) > 0 {
sd.ListValues = a.ListValues
sd.Value = ""
if err := sd.AddToFile(openAPIPath); err != nil {
if err := sd.AddToFile(c.OpenAPIPath); err != nil {
return err
}
}
@@ -165,3 +173,32 @@ func validateSchemaTypes(sc *spec.Schema) error {
}
return nil
}
func (c SetterCreator) validateSetterInfo() error {
// check if substitution with same name exists and throw error
ref, err := spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SubstitutionDefinitionPrefix + c.Name)
if err != nil {
return err
}
subst, _ := openapi.Resolve(&ref)
// if substitution already exists with the input setter name, throw error
if subst != nil {
return errors.Errorf("substitution with name %q already exists, "+
"substitution and setter can't have same name", c.Name)
}
// check if setter with same name exists and throw error
ref, err = spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SetterDefinitionPrefix + c.Name)
if err != nil {
return err
}
setter, _ := openapi.Resolve(&ref)
// if setter already exists with the input setter name, throw error
if setter != nil {
return errors.Errorf("setter with name %q already exists, "+
"if you want to modify it, please delete the existing setter and recreate it", c.Name)
}
return nil
}

View File

@@ -47,15 +47,23 @@ type SubstitutionCreator struct {
// Path to openAPI file
OpenAPIPath string
OpenAPIFileName string
RecurseSubPackages bool
// Path to resources folder
ResourcesPath string
}
func (c *SubstitutionCreator) Filter(input []*yaml.RNode) ([]*yaml.RNode, error) {
return nil, c.Create(c.OpenAPIPath, c.ResourcesPath)
return nil, c.Create()
}
func (c SubstitutionCreator) Create(openAPIPath, resourcesPath string) error {
func (c SubstitutionCreator) Create() error {
err := c.validateSubstitutionInfo()
if err != nil {
return err
}
values, err := markersAndRefs(c.Name, c.Pattern)
if err != nil {
return err
@@ -70,22 +78,22 @@ func (c SubstitutionCreator) Create(openAPIPath, resourcesPath string) error {
// the input substitution definition is updated in the openAPI file and then parsed
// to check if there are any cycles in nested substitutions, if there are
// any, the openAPI file will be reverted to current state and error is thrown
stat, err := os.Stat(openAPIPath)
stat, err := os.Stat(c.OpenAPIPath)
if err != nil {
return err
}
curOpenAPI, err := ioutil.ReadFile(openAPIPath)
curOpenAPI, err := ioutil.ReadFile(c.OpenAPIPath)
if err != nil {
return err
}
if err := d.AddToFile(openAPIPath); err != nil {
if err := d.AddToFile(c.OpenAPIPath); err != nil {
return err
}
// Load the updated definitions
if err := openapi.AddSchemaFromFile(openAPIPath); err != nil {
if err := openapi.AddSchemaFromFile(c.OpenAPIPath); err != nil {
return err
}
@@ -105,19 +113,19 @@ func (c SubstitutionCreator) Create(openAPIPath, resourcesPath string) error {
return err
}
err = c.CreateSettersForSubstitution(openAPIPath)
err = c.CreateSettersForSubstitution(c.OpenAPIPath)
if err != nil {
return err
}
// Load the updated definitions after setters are created
if err := openapi.AddSchemaFromFile(openAPIPath); err != nil {
if err := openapi.AddSchemaFromFile(c.OpenAPIPath); err != nil {
return err
}
// revert openAPI file if there are cycles detected in created input substitution
if err := checkForCycles(ext, visited); err != nil {
if writeErr := ioutil.WriteFile(openAPIPath, curOpenAPI, stat.Mode().Perm()); writeErr != nil {
if writeErr := ioutil.WriteFile(c.OpenAPIPath, curOpenAPI, stat.Mode().Perm()); writeErr != nil {
return writeErr
}
return err
@@ -130,7 +138,7 @@ func (c SubstitutionCreator) Create(openAPIPath, resourcesPath string) error {
}
// Update the resources with the substitution reference
inout := &kio.LocalPackageReadWriter{PackagePath: resourcesPath}
inout := &kio.LocalPackageReadWriter{PackagePath: c.ResourcesPath}
err = kio.Pipeline{
Inputs: []kio.Reader{inout},
Filters: []kio.Filter{kio.FilterAll(a)},
@@ -203,7 +211,7 @@ func (c SubstitutionCreator) CreateSettersForSubstitution(openAPIPath string) er
// continue if ref is a substitution, as it has already been checked if it exists
// as part of preRunE
if strings.Contains(value.Ref, fieldmeta.SubstitutionDefinitionPrefix) {
fmt.Printf("found a substitution with name %s\n", value.Marker)
fmt.Printf("found a substitution with name %q\n", value.Marker)
continue
}
setterObj, err := y.Pipe(yaml.Lookup(
@@ -420,3 +428,32 @@ func min(a int, b int) int {
}
return b
}
func (c SubstitutionCreator) validateSubstitutionInfo() error {
// check if substitution with same name exists and throw error
ref, err := spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SubstitutionDefinitionPrefix + c.Name)
if err != nil {
return err
}
subst, _ := openapi.Resolve(&ref)
// if substitution already exists with the input substitution name, throw error
if subst != nil {
return errors.Errorf("substitution with name %q already exists", c.Name)
}
// check if setter with same name exists and throw error
ref, err = spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SetterDefinitionPrefix + c.Name)
if err != nil {
return err
}
setter, _ := openapi.Resolve(&ref)
// if setter already exists with input substitution name, throw error
if setter != nil {
return errors.Errorf(fmt.Sprintf("setter with name %q already exists, "+
"substitution and setter can't have same name", c.Name))
}
return nil
}