Example #1
0
// TODO: Consider using a mocking library instead or fully fleshing this out into a fake impl and putting it in some
// generally available location
func (f *Factory) ValidateBytes(data []byte) error {
	var obj interface{}
	out, err := k8syaml.ToJSON(data)
	if err != nil {
		return err
	}
	data = out
	if err := json.Unmarshal(data, &obj); err != nil {
		return err
	}
	fields, ok := obj.(map[string]interface{})
	if !ok {
		return fmt.Errorf("error in unmarshaling data %s", string(data))
	}
	// Note: This only supports the 2 api versions we expect from the test it is currently supporting.
	groupVersion := fields["apiVersion"]
	switch groupVersion {
	case "v1":
		return f.defaultSchema.ValidateBytes(data)
	case "extensions/v1beta1":
		return f.extensionsSchema.ValidateBytes(data)
	default:
		return fmt.Errorf("Unsupported API version %s", groupVersion)
	}
}
Example #2
0
// NewDelta accepts two JSON or YAML documents and calculates the difference
// between them.  It returns a Delta object which can be used to resolve
// conflicts against a third version with a common parent, or an error
// if either document is in error.
func NewDelta(from, to []byte) (*Delta, error) {
	d := &Delta{}
	before, err := yaml.ToJSON(from)
	if err != nil {
		return nil, err
	}
	after, err := yaml.ToJSON(to)
	if err != nil {
		return nil, err
	}
	diff, err := jsonpatch.CreateMergePatch(before, after)
	if err != nil {
		return nil, err
	}
	glog.V(6).Infof("Patch created from:\n%s\n%s\n%s", string(before), string(after), string(diff))
	d.original = before
	d.edit = diff
	return d, nil
}
Example #3
0
// Apply attempts to apply the changes described by Delta onto latest,
// returning an error if the changes cannot be applied cleanly.
// IsConflicting will be true if the changes overlap, otherwise a
// generic error will be returned.
func (d *Delta) Apply(latest []byte) ([]byte, error) {
	base, err := yaml.ToJSON(latest)
	if err != nil {
		return nil, err
	}
	changes, err := jsonpatch.CreateMergePatch(d.original, base)
	if err != nil {
		return nil, err
	}
	diff1 := make(map[string]interface{})
	if err := json.Unmarshal(d.edit, &diff1); err != nil {
		return nil, err
	}
	diff2 := make(map[string]interface{})
	if err := json.Unmarshal(changes, &diff2); err != nil {
		return nil, err
	}
	for _, fn := range d.preconditions {
		hold1, _ := fn(diff1)
		hold2, _ := fn(diff2)
		if !hold1 || !hold2 {
			return nil, ErrPreconditionFailed
		}
	}

	glog.V(6).Infof("Testing for conflict between:\n%s\n%s", string(d.edit), string(changes))
	hasConflicts, err := strategicpatch.HasConflicts(diff1, diff2)
	if err != nil {
		return nil, err
	}
	if hasConflicts {
		return nil, ErrConflict
	}

	return jsonpatch.MergePatch(base, d.edit)
}