github.com/kiali/kiali@v1.84.0/business/layer.go (about)

     1  package business
     2  
     3  import (
     4  	"k8s.io/client-go/tools/clientcmd/api"
     5  
     6  	"github.com/kiali/kiali/config"
     7  	"github.com/kiali/kiali/kubernetes"
     8  	"github.com/kiali/kiali/kubernetes/cache"
     9  	"github.com/kiali/kiali/prometheus"
    10  	"github.com/kiali/kiali/tracing"
    11  )
    12  
    13  // Layer is a container for fast access to inner services.
    14  // A business layer is created per token/user. Any data that
    15  // needs to be saved across layers is saved in the Kiali Cache.
    16  type Layer struct {
    17  	App            AppService
    18  	Health         HealthService
    19  	IstioConfig    IstioConfigService
    20  	IstioStatus    IstioStatusService
    21  	IstioCerts     IstioCertsService
    22  	Tracing        TracingService
    23  	Mesh           MeshService
    24  	Namespace      NamespaceService
    25  	ProxyLogging   ProxyLoggingService
    26  	ProxyStatus    ProxyStatusService
    27  	RegistryStatus RegistryStatusService
    28  	Svc            SvcService
    29  	TLS            TLSService
    30  	Validations    IstioValidationsService
    31  	Workload       WorkloadService
    32  }
    33  
    34  // Global clientfactory and prometheus clients.
    35  var (
    36  	clientFactory       kubernetes.ClientFactory
    37  	kialiCache          cache.KialiCache
    38  	poller              ControlPlaneMonitor
    39  	prometheusClient    prometheus.ClientInterface
    40  	tracingClientLoader func() tracing.ClientInterface
    41  )
    42  
    43  // Start sets the globals necessary for the business layer.
    44  // TODO: Refactor out global vars.
    45  func Start(cf kubernetes.ClientFactory, controlPlaneMonitor ControlPlaneMonitor, cache cache.KialiCache, prom prometheus.ClientInterface, traceClientLoader func() tracing.ClientInterface) {
    46  	clientFactory = cf
    47  	kialiCache = cache
    48  	poller = controlPlaneMonitor
    49  	prometheusClient = prom
    50  	tracingClientLoader = traceClientLoader
    51  }
    52  
    53  // Get the business.Layer
    54  func Get(authInfo *api.AuthInfo) (*Layer, error) {
    55  	// Creates new k8s clients based on the current users token
    56  	userClients, err := clientFactory.GetClients(authInfo)
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  
    61  	var traceClient tracing.ClientInterface
    62  	// This check is only necessary because many of the unit tests don't properly initialize the tracingClientLoader global variable.
    63  	// In a real environment, Start should always be called before Get so the global should always be initialized.
    64  	if tracingClientLoader != nil {
    65  		traceClient = tracingClientLoader()
    66  	}
    67  
    68  	kialiSAClient := clientFactory.GetSAClients()
    69  	return NewWithBackends(userClients, kialiSAClient, prometheusClient, traceClient), nil
    70  }
    71  
    72  // SetWithBackends allows for specifying the ClientFactory and Prometheus clients to be used.
    73  // Mock friendly. Used only with tests.
    74  func SetWithBackends(cf kubernetes.ClientFactory, prom prometheus.ClientInterface) {
    75  	clientFactory = cf
    76  	prometheusClient = prom
    77  }
    78  
    79  // NewWithBackends creates the business layer using the passed k8sClients and prom clients.
    80  // Note that the client passed here should *not* be the Kiali ServiceAccount client.
    81  // It should be the user client based on the logged in user's token.
    82  func NewWithBackends(userClients map[string]kubernetes.ClientInterface, kialiSAClients map[string]kubernetes.ClientInterface, prom prometheus.ClientInterface, traceClient tracing.ClientInterface) *Layer {
    83  	return newLayer(userClients, kialiSAClients, prom, traceClient, kialiCache, config.Get())
    84  }
    85  
    86  func newLayer(
    87  	userClients map[string]kubernetes.ClientInterface,
    88  	kialiSAClients map[string]kubernetes.ClientInterface,
    89  	prom prometheus.ClientInterface,
    90  	traceClient tracing.ClientInterface,
    91  	cache cache.KialiCache,
    92  	conf *config.Config,
    93  ) *Layer {
    94  	temporaryLayer := &Layer{}
    95  
    96  	homeClusterName := conf.KubernetesConfig.ClusterName
    97  
    98  	// TODO: Modify the k8s argument to other services to pass the whole k8s map if needed
    99  	temporaryLayer.App = AppService{prom: prom, userClients: userClients, businessLayer: temporaryLayer}
   100  	temporaryLayer.Health = HealthService{prom: prom, businessLayer: temporaryLayer, userClients: userClients}
   101  	temporaryLayer.IstioConfig = IstioConfigService{config: *conf, userClients: userClients, kialiCache: cache, businessLayer: temporaryLayer, controlPlaneMonitor: poller}
   102  	temporaryLayer.IstioStatus = NewIstioStatusService(userClients, temporaryLayer, poller)
   103  	temporaryLayer.IstioCerts = IstioCertsService{k8s: userClients[homeClusterName], businessLayer: temporaryLayer}
   104  	temporaryLayer.Namespace = NewNamespaceService(userClients, kialiSAClients, cache, conf)
   105  	temporaryLayer.Mesh = NewMeshService(kialiSAClients, cache, temporaryLayer.Namespace, *conf)
   106  	temporaryLayer.ProxyStatus = ProxyStatusService{kialiSAClients: kialiSAClients, kialiCache: cache, businessLayer: temporaryLayer}
   107  	// Out of order because it relies on ProxyStatus
   108  	temporaryLayer.ProxyLogging = ProxyLoggingService{userClients: userClients, proxyStatus: &temporaryLayer.ProxyStatus}
   109  	temporaryLayer.RegistryStatus = RegistryStatusService{kialiCache: cache}
   110  	temporaryLayer.TLS = TLSService{userClients: userClients, kialiCache: cache, businessLayer: temporaryLayer}
   111  	temporaryLayer.Svc = SvcService{config: *conf, kialiCache: cache, businessLayer: temporaryLayer, prom: prom, userClients: userClients}
   112  	temporaryLayer.Validations = IstioValidationsService{userClients: userClients, businessLayer: temporaryLayer}
   113  	temporaryLayer.Workload = *NewWorkloadService(userClients, prom, cache, temporaryLayer, conf)
   114  
   115  	temporaryLayer.Tracing = NewTracingService(conf, traceClient, &temporaryLayer.Svc, &temporaryLayer.Workload)
   116  	return temporaryLayer
   117  }
   118  
   119  // NewLayer creates the business layer using the passed k8sClients and prom clients.
   120  // Note that the client passed here should *not* be the Kiali ServiceAccount client.
   121  // It should be the user client based on the logged in user's token.
   122  func NewLayer(conf *config.Config, cache cache.KialiCache, cf kubernetes.ClientFactory, prom prometheus.ClientInterface, traceClient tracing.ClientInterface, cpm ControlPlaneMonitor, authInfo *api.AuthInfo) (*Layer, error) {
   123  	userClients, err := cf.GetClients(authInfo)
   124  	if err != nil {
   125  		return nil, err
   126  	}
   127  
   128  	kialiSAClients := cf.GetSAClients()
   129  	return newLayer(userClients, kialiSAClients, prom, traceClient, cache, conf), nil
   130  }