func createCRD(cSets Clientsets, logger log.Logger) error {
	if _, err := habv1beta2controller.CreateCRD(cSets.ApiextensionsClientset); err != nil {
		if !apierrors.IsAlreadyExists(err) {
			return errors.Wrap(err, "create Habitat CRD failed")
		}
		level.Info(logger).Log("msg", "Habitat CRD already exists, continuing")
		return nil
	}
	level.Info(logger).Log("msg", "created Habitat CRD")
	return nil
}
createCRD creates Habitat CRD in the cluster, provided the operator has 'create'
permission on apiextensions.k8s.io/CustomResourceDefinitions type
if it does not then this fails, logs information about the existing CRD.
package main
import (
	"context"
	"flag"
	"fmt"
	"os"
	"os/signal"
	"runtime"
	"sync"
	"syscall"
	"time"
	"github.com/go-kit/kit/log"
	"github.com/go-kit/kit/log/level"
	"github.com/pkg/errors"
	apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	kubeinformers "k8s.io/client-go/informers"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	habclientset "github.com/habitat-sh/habitat-operator/pkg/client/clientset/versioned"
	habinformers "github.com/habitat-sh/habitat-operator/pkg/client/informers/externalversions"
	habv1beta2controller "github.com/habitat-sh/habitat-operator/pkg/controller/v1beta2"
	"github.com/habitat-sh/habitat-operator/pkg/version"
)
const resyncPeriod = 30 * time.Second
type Clientsets struct {
	KubeClientset          *kubernetes.Clientset
	HabClientset           *habclientset.Clientset
	ApiextensionsClientset *apiextensionsclient.Clientset
}
type FlagOpts struct {
	Namespace           string
	AssumeCRDRegistered bool
}
func run() int {
	kubeconfig := flag.String("kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.")
	verbose := flag.Bool("verbose", false, "Enable verbose logging.")
	namespace := flag.String("namespace", metav1.NamespaceAll, "Specify namespace this Operator will be monitoring. (default: Monitors all namespaces)")
	assumeCRDRegistered := flag.Bool("assume-crd-registered", false, "If cluster admin has already registered CRD then provide this flag with namespace flag.")
	flag.Parse()
	logger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
	logger = log.With(logger, "ts", log.DefaultTimestamp)
	if *verbose {
		logger = level.NewFilter(logger, level.AllowDebug())
	} else {
		logger = level.NewFilter(logger, level.AllowInfo())
	}
	flags := &FlagOpts{
		Namespace:           *namespace,
		AssumeCRDRegistered: *assumeCRDRegistered,
	}
	config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
	if err != nil {
		level.Error(logger).Log("msg", err)
		return 1
	}
	apiextensionsClientset, err := apiextensionsclient.NewForConfig(config)
	if err != nil {
		level.Error(logger).Log("msg", err)
		return 1
	}
	habClientset, err := habclientset.NewForConfig(config)
	if err != nil {
		level.Error(logger).Log("msg", err)
		return 1
	}
	kubeClientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		level.Error(logger).Log("msg", err)
		return 1
	}
	if flags.Namespace == metav1.NamespaceAll {
		level.Info(logger).Log("msg", "Running operator at cluster scope, looking for all the namespaces")
		if _, err := kubeClientset.CoreV1().Namespaces().List(metav1.ListOptions{}); err != nil {
			level.Error(logger).Log("msg", errors.Wrap(err, "Operator does not have cluster wide permissions"))
			return 1
		}
	}
	ctx, cancelFunc := context.WithCancel(context.Background())
	defer cancelFunc()
	var wg sync.WaitGroup
	wg.Add(1)
	cSets := Clientsets{
		KubeClientset:          kubeClientset,
		HabClientset:           habClientset,
		ApiextensionsClientset: apiextensionsClientset,
	}
	if err := v1beta2(ctx, &wg, cSets, logger, flags); err != nil {
		level.Error(logger).Log("msg", err)
		return 1
	}
	term := make(chan os.Signal, 2)
	signal.Notify(term, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		<-term
		level.Info(logger).Log("msg", "received termination signal, exiting gracefully...")
		cancelFunc()
		<-term
		os.Exit(1)
	}()
	<-ctx.Done()
	wg.Wait()
	level.Info(logger).Log("msg", "controllers stopped, exiting")
	return 0
}