func Pluck(obj map[string]interface{}, path ...string) (interface{}, bool) {
	var curr interface{} = obj
	for _, component := range path {
		currObj, isMap := curr.(map[string]interface{})
		if !isMap {
			return nil, false
		}
		var exists bool
		curr, exists = currObj[component]
		if !exists {
			return nil, false
		}
	}
	return curr, true
}
Pluck obtains the property identified by the string components in `path`. For example,
`Pluck(foo, "bar", "baz")` returns `foo.bar.baz`.
package openapi
import (
	"fmt"
	"github.com/pulumi/pulumi-kubernetes/provider/v3/pkg/kinds"
	logger "github.com/pulumi/pulumi/sdk/v3/go/common/util/logging"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/apimachinery/pkg/util/jsonmergepatch"
	"k8s.io/apimachinery/pkg/util/strategicpatch"
	"k8s.io/cli-runtime/pkg/resource"
	"k8s.io/client-go/discovery"
	"k8s.io/kube-openapi/pkg/util/proto"
	"k8s.io/kubectl/pkg/scheme"
	"k8s.io/kubectl/pkg/util/openapi"
	"k8s.io/kubectl/pkg/util/openapi/validation"
)
func ValidateAgainstSchema(
	resources openapi.Resources, obj *unstructured.Unstructured,
) error {
	bytes, err := obj.MarshalJSON()
	if err != nil {
		return err
	}
	gvk := obj.GroupVersionKind()
	resSchema := resources.LookupResource(gvk)
	if resSchema == nil {
		return fmt.Errorf("cluster does not support resource type '%s'", gvk.String())
	}
	specValidator := validation.NewSchemaValidation(resources)
	return specValidator.ValidateBytes(bytes)
}
func PatchForResourceUpdate(
	resources openapi.Resources, lastSubmitted, currentSubmitted, liveOldObj *unstructured.Unstructured,
) (patch []byte, patchType types.PatchType, lookupPatchMeta strategicpatch.LookupPatchMeta, err error) {
	lastSubmittedJSON, err := lastSubmitted.MarshalJSON()
	if err != nil {
		return nil, "", nil, err
	}
	currentSubmittedJSON, err := currentSubmitted.MarshalJSON()
	if err != nil {
		return nil, "", nil, err
	}
	liveOldJSON, err := liveOldObj.MarshalJSON()
	if err != nil {
		return nil, "", nil, err
	}
	kind := kinds.Kind(lastSubmitted.GetKind())
	if knownKind, _ := kind.Namespaced(); !knownKind {
		patch, patchType, err = MergePatch(
			lastSubmitted, lastSubmittedJSON, currentSubmittedJSON, liveOldJSON,
		)
		return patch, patchType, lookupPatchMeta, err
	}
	patch, patchType, lookupPatchMeta, err = StrategicMergePatch(
		resources, lastSubmitted, lastSubmittedJSON, currentSubmittedJSON, liveOldJSON,
	)
	if err != nil {
		patch, patchType, err = MergePatch(
			lastSubmitted, lastSubmittedJSON, currentSubmittedJSON, liveOldJSON,
		)
	}
	return patch, patchType, lookupPatchMeta, err
}
func StrategicMergePatch(
	resources openapi.Resources, lastSubmitted *unstructured.Unstructured, lastSubmittedJSON, currentSubmittedJSON, liveOldJSON []byte,
) (patch []byte, patchType types.PatchType, lookupPatchMeta strategicpatch.LookupPatchMeta, err error) {
	gvk := lastSubmitted.GroupVersionKind()
	if resSchema := resources.LookupResource(gvk); resSchema != nil {
		logger.V(1).Infof("Attempting to update '%s' '%s/%s' with strategic merge",
			gvk.String(), lastSubmitted.GetNamespace(), lastSubmitted.GetName())
		patch, patchType, lookupPatchMeta, err = strategicMergePatch(
			gvk, resSchema, lastSubmittedJSON, currentSubmittedJSON, liveOldJSON)
	}
	if err != nil {
		return patch, patchType, lookupPatchMeta, err
	}
	return patch, patchType, lookupPatchMeta, nil
}
func MergePatch(
	lastSubmitted *unstructured.Unstructured, lastSubmittedJSON, currentSubmittedJSON, liveOldJSON []byte,
) (patch []byte, patchType types.PatchType, err error) {
	gvk := lastSubmitted.GroupVersionKind()
	logger.V(1).Infof("Attempting to update '%s' '%s/%s' with JSON merge",
		gvk.String(), lastSubmitted.GetNamespace(), lastSubmitted.GetName())
	patch, patchType, err = jsonMergePatch(lastSubmittedJSON, currentSubmittedJSON, liveOldJSON)
	return patch, patchType, err
}
func SupportsDryRun(dryRunVerifier *resource.DryRunVerifier, gvk schema.GroupVersionKind) bool {
	if err := dryRunVerifier.HasSupport(gvk); err != nil {
		return false
	}
	return true
}