func getReplicasFromObject(obj interface{}) (int, error) {
	v, err := conversion.EnforcePtr(obj)
	if err != nil {
		return 0, err
	}
	err = reflectconversions.EnforceStruct(v)
	if err != nil {
		return 0, err
	}
	specField := v.FieldByName("Spec")
	if !specField.IsValid() {
		return 0, fmt.Errorf("struct lacks struct Spec")
	}
	err = reflectconversions.EnforceStruct(v)
	if err != nil {
		return 0, err
	}
	replicasField := specField.FieldByName("Replicas")
	if !replicasField.IsValid() {
		return 0, fmt.Errorf("struct lacks field replicas")
	}
	replicasV, err := conversion.EnforcePtr(replicasField.Interface())
	if err != nil {
		return 0, err
	}
	if replicasV.Kind() != reflect.Int32 {
		return 0, fmt.Errorf("expected Replicas to be int32, but got %v: %v (%#v)", replicasV.Kind(), replicasV.Type(), replicasV.Interface())
	}
	return int(replicasV.Int()), nil
}
getReplicasFromObject uses reflect to extract the replicas from a given object
assumes path is Spec.Replicas
package expose
import (
	"context"
	"encoding/json"
	"fmt"
	"reflect"
	"github.com/getoutreach/localizer/internal/kevents"
	"github.com/getoutreach/localizer/internal/kube"
	"github.com/getoutreach/localizer/internal/reflectconversions"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	appsv1 "k8s.io/api/apps/v1"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/meta"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/conversion"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/restmapper"
	"k8s.io/client-go/tools/cache"
)
type Client struct {
	k     kubernetes.Interface
	kconf *rest.Config
	log   logrus.FieldLogger
	podStore cache.Store
	svcStore cache.Store
	rm       meta.RESTMapper
}
func NewExposer(k kubernetes.Interface, kconf *rest.Config, log logrus.FieldLogger) *Client {
	return &Client{
		k,
		kconf,
		log,
		nil,
		nil,
		nil,
	}
}
func (c *Client) Start(ctx context.Context) error {
	podInformer := kevents.GlobalCache.Core().V1().Pods().Informer()
	svcInformer := kevents.GlobalCache.Core().V1().Services().Informer()
	c.podStore = podInformer.GetStore()
	c.svcStore = svcInformer.GetStore()
	groupResources, err := restmapper.GetAPIGroupResources(c.k.Discovery())
	if err != nil {
		return err
	}
	c.rm = restmapper.NewDiscoveryRESTMapper(groupResources)
	for _, obj := range c.podStore.List() {
		p := obj.(*corev1.Pod)
		if p.Labels[ExposedPodLabel] == "true" {
			key, _ := cache.MetaNamespaceKeyFunc(p)  
			log := c.log.WithField("pod", key)
			log.Warn("removing abandoned localizer pod")
			err := c.k.CoreV1().Pods(p.Namespace).Delete(ctx, p.Name, metav1.DeleteOptions{})
			if err != nil {
				log.WithError(err).Warn("failed to remove abandoned localizer pod")
			}
			var objects []scaledObjectType
			err = json.Unmarshal([]byte(p.Annotations[ObjectsPodLabel]), &objects)
			if err != nil {
				c.log.WithError(err).Warn("failed to ensure controllers were scaled back up")
				continue
			}
			for _, obj := range objects {
				err := c.scaleObject(ctx, obj, obj.Replicas)
				if err != nil {
					c.log.WithError(err).WithField("object", obj.GetKey()).Warn("failed to restore controller scale")
					continue
				}
			}
		}
	}
	return nil
}
func (c *Client) getMapping(obj interface{}) (*meta.RESTMapping, error) {
	kind := ""
	switch obj.(type) {
	case *appsv1.Deployment:
		kind = "deployment"
	case *appsv1.StatefulSet:
		kind = "statefulset"
	}
	gk := schema.GroupKind{Group: "apps", Kind: kind}
	c.log.WithField("group", gk).Debug("looking up group")
	return c.rm.RESTMapping(gk, "v1")
}
type patchUInt32Value struct {
	Op    string `json:"op"`
	Path  string `json:"path"`
	Value uint   `json:"value"`
}
func (c *Client) scaleObject(ctx context.Context, scaledObj scaledObjectType, replicas int) error {
	payload := []patchUInt32Value{{
		Op:    "replace",
		Path:  "/spec/replicas",
		Value: uint(replicas),
	}}
	payloadBytes, err := json.Marshal(payload)
	if err != nil {
		return errors.Wrap(err, "failed to marshal scale patch body")
	}
	req := c.k.AppsV1().RESTClient().Patch(types.JSONPatchType).Resource(scaledObj.Resource).
		Namespace(scaledObj.GetNamespace()).Name(scaledObj.GetName()).Body(payloadBytes)
	c.log.WithField("url", req.URL().String()).Debug("setting replicas")
	res := req.Do(ctx)
	if res.Error() != nil {
		return res.Error()
	}
	return nil
}