func (b *Background) detectKafka(ctx context.Context, apiList *metav1.APIGroupList) {
	if b.retryDetectKafka {
		log.Trace("Determining whether we should enable the Kafka Operator integration")
		previous := viper.GetString("kafka-provision")
		if isKafkaOperatorAvailable(apiList) {
			viper.Set("kafka-provision", v1.FlagProvisionKafkaYes)
		} else {
			viper.Set("kafka-provision", v1.FlagProvisionKafkaNo)
		}
		if previous != viper.GetString("kafka-provision") {
			log.WithField("kafka-provision", viper.GetString("kafka-provision")).Info("Automatically adjusted the 'kafka-provision' flag")
		}
	} else {
		log.WithField("kafka-provision", viper.GetString("kafka-provision")).Trace("The 'kafka-provision' option is explicitly set")
	}
}
detectKafka checks whether the Kafka Operator is available
package autodetect
import (
	"context"
	"strings"
	"sync"
	"time"
	log "github.com/sirupsen/logrus"
	"github.com/spf13/viper"
	appsv1 "k8s.io/api/apps/v1"
	authenticationapi "k8s.io/api/authentication/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/apimachinery/pkg/selection"
	"k8s.io/client-go/discovery"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/manager"
	v1 "github.com/jaegertracing/jaeger-operator/pkg/apis/jaegertracing/v1"
	"github.com/jaegertracing/jaeger-operator/pkg/inject"
)
type Background struct {
	cl       client.Client
	clReader client.Reader
	dcl      discovery.DiscoveryInterface
	ticker   *time.Ticker
	firstRun         *sync.Once
	retryDetectKafka bool
	retryDetectEs    bool
}
func New(mgr manager.Manager) (*Background, error) {
	dcl, err := discovery.NewDiscoveryClientForConfig(mgr.GetConfig())
	if err != nil {
		return nil, err
	}
	return WithClients(mgr.GetClient(), dcl, mgr.GetAPIReader()), nil
}
func WithClients(cl client.Client, dcl discovery.DiscoveryInterface, clr client.Reader) *Background {
	retryDetectEs := viper.GetString("es-provision") == v1.FlagProvisionElasticsearchAuto
	retryDetectKafka := viper.GetString("kafka-provision") == v1.FlagProvisionKafkaAuto
	return &Background{
		cl:               cl,
		dcl:              dcl,
		clReader:         clr,
		retryDetectKafka: retryDetectKafka,
		retryDetectEs:    retryDetectEs,
		firstRun:         &sync.Once{},
	}
}
func (b *Background) Start() {
	b.ticker = time.NewTicker(5 * time.Second)
	done := make(chan bool)
	go func() {
		b.autoDetectCapabilities()
		done <- true
	}()
	go func() {
		for {
			select {
			case <-done:
				log.Trace("finished the first auto-detection")
			case <-b.ticker.C:
				b.autoDetectCapabilities()
			}
		}
	}()
}
func (b *Background) Stop() {
	b.ticker.Stop()
}
func (b *Background) autoDetectCapabilities() {
	ctx := context.Background()
	apiList, err := b.availableAPIs(ctx)
	if err != nil {
		log.WithError(err).Info("failed to determine the platform capabilities, auto-detected properties will remain the same until next cycle.")
	} else {
		b.firstRun.Do(func() {
			b.detectPlatform(ctx, apiList)
		})
		b.detectElasticsearch(ctx, apiList)
		b.detectKafka(ctx, apiList)
	}
	b.detectClusterRoles(ctx)
	b.cleanDeployments(ctx)
}
func (b *Background) availableAPIs(ctx context.Context) (*metav1.APIGroupList, error) {
	apiList, err := b.dcl.ServerGroups()
	if err != nil {
		return nil, err
	}
	return apiList, nil
}
func (b *Background) detectPlatform(ctx context.Context, apiList *metav1.APIGroupList) {
	if strings.EqualFold(viper.GetString("platform"), v1.FlagPlatformAutoDetect) {
		log.Trace("Attempting to auto-detect the platform")
		if isOpenShift(apiList) {
			viper.Set("platform", v1.FlagPlatformOpenShift)
		} else {
			viper.Set("platform", v1.FlagPlatformKubernetes)
		}
		log.WithField("platform", viper.GetString("platform")).Info("Auto-detected the platform")
	} else {
		log.WithField("platform", viper.GetString("platform")).Debug("The 'platform' option is explicitly set")
	}
}
func (b *Background) detectElasticsearch(ctx context.Context, apiList *metav1.APIGroupList) {
	if b.retryDetectEs {
		log.Trace("Determining whether we should enable the Elasticsearch Operator integration")
		previous := viper.GetString("es-provision")
		if isElasticsearchOperatorAvailable(apiList) {
			viper.Set("es-provision", v1.FlagProvisionElasticsearchYes)
		} else {
			viper.Set("es-provision", v1.FlagProvisionElasticsearchNo)
		}
		if previous != viper.GetString("es-provision") {
			log.WithField("es-provision", viper.GetString("es-provision")).Info("Automatically adjusted the 'es-provision' flag")
		}
	} else {
		log.WithField("es-provision", viper.GetString("es-provision")).Trace("The 'es-provision' option is explicitly set")
	}
}