func DeleteResource(
	delete func() error,
	verify func() error,
	resource string,
	opts *DeleteOptions,
	defaultWaitOptions *WaitOptions,
) error {
	if err := delete(); err != nil {
		if errors.IsNotFound(err) && opts.MustDelete {
			return fmt.Errorf("failed to delete %s; it does not exist. %+v", resource, err)
		} else if errors.IsNotFound(err) && !opts.MustDelete {
			logger.Debugf("%s is already deleted", resource)
			return nil
		}
		return fmt.Errorf("failed to delete %s. %+v", resource, err)
	}
	if !opts.Wait {
		return nil
	}
	retries := opts.retryCountOrDefault(defaultWaitOptions.retryCountOrDefault(30))
	retryInterval := opts.retryIntervalOrDefault(defaultWaitOptions.retryIntervalOrDefault(5 * time.Second))
	unitTestRetryIntervalRecord = retryInterval
	var i uint
	var err error
	for i = 0; i <= retries; i++ {
		err = verify()
		if err != nil && errors.IsNotFound(err) {
			logger.Debugf("%s was deleted after %d retries every %v seconds", resource, i, retryInterval/time.Second)
			return nil
		}
		logger.Infof("Retrying %d more times every %d seconds for %s to be deleted",
			retries-i, int(retryInterval/time.Second), resource)
		if retries-i > 0 {
			time.Sleep(retryInterval)
		}
	}
	msg := fmt.Sprintf("failed to delete %s. gave up waiting after %d retries every %v seconds. %+v",
		resource, retries, retryInterval/time.Second, err)
	if opts.ErrorOnTimeout {
		return fmt.Errorf(msg)
	}
	logger.Warningf(msg)
	return nil
}
DeleteResource implements the DeleteOptions logic around deletion of a Kubernetes resource.

The delete and verify functions used as parameters should implement and return the error from the
Kubernetes `Delete` and `Get` commands respectively.

The resource string will be used to report the resource in log and error messages. A good pattern
would be to set this string to the resource type (e.g., Deployment) and the name of the resource
(e.g., my-deployment).

The default wait options should specify sane defaults for retry count and retry interval for
deletion of the specific resource type. Only retry count and interval will be used from this
parameter.
package k8sutil
import (
	"fmt"
	"time"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func BaseKubernetesDeleteOptions() *metav1.DeleteOptions {
	p := metav1.DeletePropagationForeground
	g := int64(0)
	return &metav1.DeleteOptions{GracePeriodSeconds: &g, PropagationPolicy: &p}
}
type DeleteOptions struct {
	MustDelete bool
	WaitOptions
}
var unitTestRetryIntervalRecord time.Duration