func NewFluxHelmReleaseCRD(FluxOperatorConfig) *extensions.CustomResourceDefinition {
	return &extensions.CustomResourceDefinition{
		ObjectMeta: metav1.ObjectMeta{
			Name: "fluxhelmreleases.helm.integrations.flux.weave.works",
		},
		TypeMeta: metav1.TypeMeta{
			Kind:       "CustomResourceDefinition",
			APIVersion: "apiextensions.k8s.io/v1beta1",
		},
		Spec: extensions.CustomResourceDefinitionSpec{
			Group: "helm.integrations.flux.weave.works",
			Names: extensions.CustomResourceDefinitionNames{
				Kind:     "FluxHelmRelease",
				ListKind: "FluxHelmReleaseList",
				Plural:   "fluxhelmreleases",
			},
			Scope:   "Namespaced",
			Version: "v1alpha2",
		},
		Status: extensions.CustomResourceDefinitionStatus{
			Conditions:     []extensions.CustomResourceDefinitionCondition{},
			StoredVersions: []string{},
		},
	}
}
Create a FluxHelmRelease CRD
package installer
import (
	"fmt"
	crdutils "github.com/ant31/crd-validation/pkg"
	v1alpha1 "github.com/justinbarrick/flux-operator/pkg/apis/flux/v1alpha1"
	"github.com/justinbarrick/flux-operator/pkg/utils"
	corev1 "k8s.io/api/core/v1"
	v1beta1 "k8s.io/api/extensions/v1beta1"
	rbacv1 "k8s.io/api/rbac/v1"
	extensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/serializer/json"
	"os"
	"reflect"
	"strconv"
)
type FluxOperatorConfig struct {
	Name string
	Namespace string
	Cluster bool
	ServiceAccount string
	ClusterRole string
	DisableRBAC bool
	DisableClusterRoles bool
	DisableRoles bool
	GitSecret string
	FluxOperatorImage string
	FluxOperatorVersion string
	FluxImage string
	FluxVersion string
	HelmOperatorImage string
	HelmOperatorVersion string
	MemcachedImage string
	MemcachedVersion string
	TillerImage string
	TillerVersion string
	FluxNamespace string
}
func GetName(config FluxOperatorConfig) string {
	if config.Name != "" {
		return config.Name
	} else {
		return "flux-operator"
	}
}
func GetClusterRole(config FluxOperatorConfig) string {
	if config.ClusterRole == "" {
		return GetName(config)
	} else {
		return config.ClusterRole
	}
}
func GetServiceAccountName(config FluxOperatorConfig) string {
	if config.DisableRBAC == true {
		return ""
	} else if config.ServiceAccount != "" {
		return config.ServiceAccount
	} else {
		return GetName(config)
	}
}
func GetNamespace(config FluxOperatorConfig) string {
	if config.Namespace != "" {
		return config.Namespace
	} else {
		return "default"
	}
}
func GetFluxOperatorImage(config FluxOperatorConfig) string {
	image := utils.FluxOperatorImage
	version := "latest"
	if config.FluxOperatorImage != "" {
		image = config.FluxOperatorImage
	}
	if config.FluxOperatorVersion != "" {
		version = config.FluxOperatorVersion
	}
	return fmt.Sprintf("%s:%s", image, version)
}
func NewFluxCRD(config FluxOperatorConfig) *extensions.CustomResourceDefinition {
	scope := "Namespaced"
	if config.Cluster {
		scope = "Cluster"
	}
	spec := "github.com/justinbarrick/flux-operator/pkg/apis/flux/v1alpha1.Flux"
	crd := crdutils.NewCustomResourceDefinition(crdutils.Config{
		SpecDefinitionName:    spec,
		EnableValidation:      true,
		ResourceScope:         scope,
		Group:                 "flux.codesink.net",
		Kind:                  "Flux",
		Version:               "v1alpha1",
		Plural:                "fluxes",
		GetOpenAPIDefinitions: v1alpha1.GetOpenAPIDefinitions,
	})
	crd.Status = extensions.CustomResourceDefinitionStatus{
		Conditions:     []extensions.CustomResourceDefinitionCondition{},
		StoredVersions: []string{},
	}
	return crd
}