func getGroupVersionKind(config map[string]interface{}) (schema.GroupVersionKind, error) {
	gvk := schema.GroupVersionKind{}
	if gv, found := config["apiVersion"]; found {
		casted, ok := gv.(string)
		if !ok {
			return gvk, fmt.Errorf("Expected string for apiVersion, found %T", gv)
		}
		s := strings.Split(casted, "/")
		if len(s) != 1 {
			gvk.Group = s[0]
		}
		gvk.Version = s[len(s)-1]
	} else {
		return gvk, fmt.Errorf("Missing apiVersion in Kind %v", config)
	}
	if k, found := config["kind"]; found {
		casted, ok := k.(string)
		if !ok {
			return gvk, fmt.Errorf("Expected string for kind, found %T", k)
		}
		gvk.Kind = casted
	} else {
		return gvk, fmt.Errorf("Missing kind in Kind %v", config)
	}
	return gvk, nil
}
getGroupVersionKind returns the GroupVersionKind of the object
package parse
import (
	"fmt"
	"reflect"
	"strings"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/kube-openapi/pkg/util/proto"
	"k8s.io/kubectl/pkg/apply"
)
func nilSafeLookup(key string, from map[string]interface{}) (interface{}, bool) {
	if from != nil {
		value, found := from[key]
		return value, found
	}
	return nil, false
}
func boundsSafeLookup(index int, from []interface{}) (interface{}, bool) {
	if from != nil && len(from) > index {
		return from[index], true
	}
	return nil, false
}
func keysUnion(maps ...map[string]interface{}) []string {
	keys := map[string]interface{}{}
	for _, m := range maps {
		for k := range m {
			keys[k] = nil
		}
	}
	result := []string{}
	for key := range keys {
		result = append(result, key)
	}
	return result
}
func max(values ...int) int {
	v := 0
	for _, i := range values {
		if i > v {
			v = i
		}
	}
	return v
}
func getType(args ...interface{}) (reflect.Type, error) {
	var last interface{}
	for _, next := range args {
		if next == nil {
			continue
		}
		if last == nil {
			last = next
			continue
		}
		if reflect.TypeOf(last).Kind() != reflect.TypeOf(next).Kind() {
			return nil, fmt.Errorf("missmatching non-nil types for the same field: %T %T", last, next)
		}
	}
	return reflect.TypeOf(last), nil
}
func getFieldMeta(s proto.Schema, name string) (apply.FieldMetaImpl, error) {
	m := apply.FieldMetaImpl{}
	if s != nil {
		ext := s.GetExtensions()
		if e, found := ext["x-kubernetes-patch-strategy"]; found {
			strategy, ok := e.(string)
			if !ok {
				return apply.FieldMetaImpl{}, fmt.Errorf("Expected string for x-kubernetes-patch-strategy by got %T", e)
			}
			strategies := strings.Split(strategy, ",")
			if len(strategies) > 2 {
				return apply.FieldMetaImpl{}, fmt.Errorf("Expected between 0 and 2 elements for x-kubernetes-patch-merge-strategy by got %v", strategies)
			}
			m.MergeType = strategies[0]
		}
		if k, found := ext["x-kubernetes-patch-merge-key"]; found {
			key, ok := k.(string)
			if !ok {
				return apply.FieldMetaImpl{}, fmt.Errorf("Expected string for x-kubernetes-patch-merge-key by got %T", k)
			}
			m.MergeKeys = apply.MergeKeys(strings.Split(key, ","))
		}
	}
	m.Name = name
	return m, nil
}
func getCommonGroupVersionKind(recorded, local, remote map[string]interface{}) (schema.GroupVersionKind, error) {
	recordedGVK, err := getGroupVersionKind(recorded)
	if err != nil {
		return schema.GroupVersionKind{}, err
	}
	localGVK, err := getGroupVersionKind(local)
	if err != nil {
		return schema.GroupVersionKind{}, err
	}
	remoteGVK, err := getGroupVersionKind(remote)
	if err != nil {
		return schema.GroupVersionKind{}, err
	}
	if !reflect.DeepEqual(recordedGVK, localGVK) || !reflect.DeepEqual(localGVK, remoteGVK) {
		return schema.GroupVersionKind{},
			fmt.Errorf("group version kinds do not match (recorded: %v local: %v remote: %v)",
				recordedGVK, localGVK, remoteGVK)
	}
	return recordedGVK, nil
}