Repository: kiali/kiali

Issue:
Consolidate CA file config options
### What do you want to improve?

How CAs are handled in the Kiali config and how they are applied across requests in the app.

### What is the current behavior?

Kiali has a number of ways to provide a CA file depending on what exactly you are trying to apply the CA to. You can apply a separate CA file for each one of the auth options including each one of the external services. But CA bundles applied to one service e.g. prometheus don't apply to the other services e.g. grafana so if you have multiple services that share a custom CA, you need to set the config option for each one.

Also when you provide a CA bundle, it completely replaces the defaults that Kiali uses like the `service-account.ca`. This is probably not the desired behavior. You want Kiali to continue trusting the in cluster CA _in addition to_ the custom CA you are providing. Adding a new bundle should be additive.

### What is the new behavior?

A single config option to provide a CA bundle for the whole Kiali app. When a custom CA is provided, it is added to the existing CA(s) that the Kiali app currently uses like the in cluster CA.

Hints from issue comments:

Solution patch:
diff --git a/.gitleaks.toml b/.gitleaks.toml
index 425e1a2ea..01e1befef 100644
--- a/.gitleaks.toml
+++ b/.gitleaks.toml
@@ -6,6 +6,7 @@
     '''business/testdata/ca\.key''',
     '''business/testdata/ca2\.crt''',
     '''business/testdata/ca2\.key''',
+    '''config/testdata/test-ca\.pem''',
     '''hack/istio/multicluster/env\.sh''',
     '''hack/istio/multicluster/setup-keycloak\.sh''',
   ]
diff --git a/business/controlplane_monitor.go b/business/controlplane_monitor.go
index 031720cca..1db806f07 100644
--- a/business/controlplane_monitor.go
+++ b/business/controlplane_monitor.go
@@ -13,10 +13,10 @@ import (
 
 	"k8s.io/apimachinery/pkg/util/wait"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/models"
 )
diff --git a/business/dashboards.go b/business/dashboards.go
index fa9e41ed8..ec948a318 100644
--- a/business/dashboards.go
+++ b/business/dashboards.go
@@ -67,7 +67,7 @@ func NewDashboardsService(conf *config.Config, grafana *grafana.Service, namespa
 func (in *DashboardsService) prom() (prometheus.ClientInterface, error) {
 	// Lazy init
 	if in.promClient == nil {
-		client, err := prometheus.NewClientForConfig(in.promConfig)
+		client, err := prometheus.NewClientForConfig(*in.conf)
 		if err != nil {
 			return nil, fmt.Errorf("cannot initialize Prometheus Client: %v", err)
 		}
diff --git a/business/istio_config.go b/business/istio_config.go
index eedd7af80..a4773ea47 100644
--- a/business/istio_config.go
+++ b/business/istio_config.go
@@ -22,9 +22,9 @@ import (
 	k8s_networking_v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
 	k8s_networking_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/observability"
diff --git a/business/istio_status.go b/business/istio_status.go
index 783d1be53..66b2bc7f7 100644
--- a/business/istio_status.go
+++ b/business/istio_status.go
@@ -7,10 +7,10 @@ import (
 
 	"k8s.io/apimachinery/pkg/labels"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/observability"
@@ -105,7 +105,7 @@ func (iss *IstioStatusService) getIstioComponentStatus(ctx context.Context, clus
 	}
 
 	var istiodStatus kubernetes.IstioComponentStatus
-	var isManaged = false
+	isManaged := false
 	for _, cp := range mesh.ControlPlanes {
 		if cp.Cluster.Name == cluster {
 			istiodStatus = append(istiodStatus, kubernetes.ComponentStatus{
@@ -367,7 +367,7 @@ func (iss *IstioStatusService) getAddonStatus(cluster string, name string, enabl
 
 	status := kubernetes.ComponentHealthy
 	// Call the addOn service endpoint to find out whether is reachable or not
-	_, statusCode, _, err := httputil.HttpGet(url, auth, 10*time.Second, nil, nil)
+	_, statusCode, _, err := httputil.HttpGet(url, auth, 10*time.Second, nil, nil, iss.conf)
 	if err != nil || statusCode > 399 {
 		log.Tracef("addon health check failed: name=[%v], url=[%v], code=[%v]", name, url, statusCode)
 		status = kubernetes.ComponentUnreachable
diff --git a/business/istio_validations.go b/business/istio_validations.go
index 7e06ef512..3b1f5fdb8 100644
--- a/business/istio_validations.go
+++ b/business/istio_validations.go
@@ -16,9 +16,9 @@ import (
 
 	"github.com/kiali/kiali/business/checkers"
 	"github.com/kiali/kiali/business/references"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/observability"
@@ -310,7 +310,7 @@ func (in *IstioValidationsService) Validate(ctx context.Context, cluster string,
 	}
 	vInfo.clusterInfo.istioConfig = istioConfigList
 
-	//if change detection is enabled then decide if we need to run the checkers
+	// if change detection is enabled then decide if we need to run the checkers
 	if vInfo.changeDetectionEnabled() {
 		changeDetected := detectClusterConfigChange(vInfo)
 		if !changeDetected && !vInfo.forceCheckers() {
@@ -591,7 +591,8 @@ func (in *IstioValidationsService) ValidateIstioObject(ctx context.Context, clus
 		objectCheckers = []checkers.ObjectChecker{serviceEntryChecker}
 		referenceChecker = references.ServiceEntryReferences{Conf: conf, AuthorizationPolicies: rbacDetails.AuthorizationPolicies, Namespace: namespace, Namespaces: nsNames, DestinationRules: istioConfigList.DestinationRules, ServiceEntries: istioConfigList.ServiceEntries, Sidecars: istioConfigList.Sidecars, RegistryServices: registryServices}
 	case kubernetes.Sidecars:
-		sidecarsChecker := checkers.SidecarChecker{Conf: conf,
+		sidecarsChecker := checkers.SidecarChecker{
+			Conf:    conf,
 			Cluster: cluster, Sidecars: istioConfigList.Sidecars, Namespaces: namespaces,
 			WorkloadsPerNamespace: workloadsPerNamespace, ServiceEntries: istioConfigList.ServiceEntries, RegistryServices: registryServices,
 		}
diff --git a/business/layer.go b/business/layer.go
index 1779a0a75..7a3201358 100644
--- a/business/layer.go
+++ b/business/layer.go
@@ -3,11 +3,11 @@ package business
 import (
 	"k8s.io/client-go/tools/clientcmd/api"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/prometheus"
 	"github.com/kiali/kiali/tracing"
 )
diff --git a/business/namespaces.go b/business/namespaces.go
index fab114e62..523412f8c 100644
--- a/business/namespaces.go
+++ b/business/namespaces.go
@@ -8,10 +8,10 @@ import (
 	core_v1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/errors"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/observability"
diff --git a/business/openshift_oauth.go b/business/openshift_oauth.go
index 4907e56e0..360dcdb88 100644
--- a/business/openshift_oauth.go
+++ b/business/openshift_oauth.go
@@ -122,16 +122,8 @@ func httpClientWithPool(conf *config.Config, restConfig rest.Config, systemPool
 
 // Returns a new cert Pool with the system certs appended as well as
 // any custom CA if it exists.
-func newCertPool(oAuthServerCAFilePath string) *x509.CertPool {
-	// Adding system certs in case the idp does not use the same cert as the oAuth server.
-	pool, err := x509.SystemCertPool()
-	if err != nil {
-		log.Errorf("While initializing openshift auth, unable to read system certs: %s", err)
-	}
-
-	if pool == nil {
-		pool = x509.NewCertPool()
-	}
+func newCertPool(conf *config.Config, oAuthServerCAFilePath string) *x509.CertPool {
+	pool := conf.CertPool()
 
 	if b, err := os.ReadFile(oAuthServerCAFilePath); err == nil {
 		if ok := pool.AppendCertsFromPEM(b); !ok {
@@ -158,7 +150,7 @@ func NewOpenshiftOAuthService(ctx context.Context, conf *config.Config, kialiSAC
 	ctx, cancel = context.WithDeadline(ctx, oneMinuteFromNow)
 	defer cancel()
 
-	pool := newCertPool(oAuthServerCustomCAFilePath)
+	pool := newCertPool(conf, oAuthServerCustomCAFilePath)
 
 	// TODO: We could parallelize this to potentially speed up the process.
 	for cluster, client := range kialiSAClients {
diff --git a/business/proxy_status.go b/business/proxy_status.go
index b0568798c..4e67226c1 100644
--- a/business/proxy_status.go
+++ b/business/proxy_status.go
@@ -4,9 +4,9 @@ import (
 	"context"
 	"fmt"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/models"
 )
 
diff --git a/business/registry_status.go b/business/registry_status.go
index 006386e9b..226bc4997 100644
--- a/business/registry_status.go
+++ b/business/registry_status.go
@@ -3,9 +3,9 @@ package business
 import (
 	"k8s.io/apimachinery/pkg/labels"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 )
 
diff --git a/business/services.go b/business/services.go
index c864bd186..2e09fc78b 100644
--- a/business/services.go
+++ b/business/services.go
@@ -15,9 +15,9 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	"github.com/kiali/kiali/business/checkers"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/observability"
diff --git a/business/tls.go b/business/tls.go
index 8725ca7c9..baa159d09 100644
--- a/business/tls.go
+++ b/business/tls.go
@@ -7,10 +7,10 @@ import (
 
 	security_v1 "istio.io/client-go/pkg/apis/security/v1"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/observability"
 	"github.com/kiali/kiali/util/mtls"
diff --git a/business/workloads.go b/business/workloads.go
index c55534a9f..49a5b60f3 100644
--- a/business/workloads.go
+++ b/business/workloads.go
@@ -29,10 +29,10 @@ import (
 	ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
 
 	"github.com/kiali/kiali/business/checkers"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/observability"
diff --git a/kubernetes/cache/cache.go b/cache/cache.go
similarity index 100%
rename from kubernetes/cache/cache.go
rename to cache/cache.go
diff --git a/kubernetes/cache/proxy_status.go b/cache/proxy_status.go
similarity index 100%
rename from kubernetes/cache/proxy_status.go
rename to cache/proxy_status.go
diff --git a/kubernetes/cache/registry_status.go b/cache/registry_status.go
similarity index 100%
rename from kubernetes/cache/registry_status.go
rename to cache/registry_status.go
diff --git a/kubernetes/cache/transform.go b/cache/transform.go
similarity index 100%
rename from kubernetes/cache/transform.go
rename to cache/transform.go
diff --git a/kubernetes/cache/ztunnel_dump.go b/cache/ztunnel_dump.go
similarity index 100%
rename from kubernetes/cache/ztunnel_dump.go
rename to cache/ztunnel_dump.go
diff --git a/config/config.go b/config/config.go
index cf11a82e1..86e3ed861 100644
--- a/config/config.go
+++ b/config/config.go
@@ -1,8 +1,10 @@
 package config
 
 import (
+	"crypto/x509"
 	"errors"
 	"fmt"
+	"io/fs"
 	"os"
 	"regexp"
 	"sort"
@@ -92,6 +94,14 @@ const (
 	Ztunnel                   = "ztunnel"
 )
 
+const (
+	additionalCABundle = "/kiali-cabundle/additional-ca-bundle.pem"
+	openshiftServingCA = "/kiali-cabundle/service-ca.crt"
+	// This is an alternate location for the openshift serving cert. It's unclear which
+	// one to prefer so we try reading both.
+	openshiftServingCAFromSA = "/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt"
+)
+
 // TracingProvider is the type of tracing provider that Kiali will connect to.
 type TracingProvider string
 
@@ -461,6 +471,8 @@ type OpenIdConfig struct {
 
 // DeploymentConfig provides details on how Kiali was deployed.
 type DeploymentConfig struct {
+	certPool *x509.CertPool
+
 	AccessibleNamespaces []string                 // this is no longer part of the actual config - we will generate this in Unmarshal()
 	ClusterWideAccess    bool                     `yaml:"cluster_wide_access,omitempty"`
 	DiscoverySelectors   DiscoverySelectorsConfig `yaml:"discovery_selectors,omitempty"`
@@ -721,6 +733,7 @@ func NewConfig() (c *Config) {
 		},
 		CustomDashboards: dashboards.GetBuiltInMonitoringDashboards(),
 		Deployment: DeploymentConfig{
+			certPool:           x509.NewCertPool(),
 			ClusterWideAccess:  true,
 			DiscoverySelectors: DiscoverySelectorsConfig{Default: nil, Overrides: nil},
 			InstanceName:       "kiali",
@@ -1099,6 +1112,38 @@ func (conf *Config) prepareDashboards() {
 	}
 }
 
+// loadCertPool loads system certs and additional CAs from config.
+func (conf *Config) loadCertPool(additionalCABundlePaths ...string) error {
+	if certPool, err := x509.SystemCertPool(); err != nil {
+		log.Warningf("Unable to load system cert pool. Falling back to empty cert pool. Error: %s", err)
+	} else {
+		conf.Deployment.certPool = certPool
+	}
+
+	for _, path := range additionalCABundlePaths {
+		if _, err := os.Stat(path); err != nil {
+			if errors.Is(err, fs.ErrNotExist) {
+				log.Debugf("Additional CA bundle %s does not exist. Skipping", path)
+			} else {
+				log.Debugf("Unable to read additional CA bundle %s. Skipping", path)
+			}
+			continue
+		}
+
+		log.Tracef("Adding CA bundle %s to pool", path)
+		bundle, err := os.ReadFile(path)
+		if err != nil {
+			return fmt.Errorf("unable to read CA bundle '%s': %s", path, err)
+		}
+
+		if !conf.Deployment.certPool.AppendCertsFromPEM(bundle) {
+			return fmt.Errorf("unable to append PEM bundle from file '%s': %s", path, err)
+		}
+	}
+
+	return nil
+}
+
 // Unmarshal parses the given YAML string and returns its Config object representation.
 func Unmarshal(yamlString string) (conf *Config, err error) {
 	conf = NewConfig()
@@ -1122,6 +1167,17 @@ func Unmarshal(yamlString string) (conf *Config, err error) {
 
 	conf.prepareDashboards()
 
+	additionalCABundles := []string{additionalCABundle}
+	// Auth strategy isn't a great proxy for whether the cluster is running on openshift or not
+	// but the config is the very first thing loaded so we don't have access to a client.
+	if conf.Auth.Strategy == AuthStrategyOpenshift {
+		additionalCABundles = append(additionalCABundles, openshiftServingCAFromSA, openshiftServingCA)
+	}
+	if err := conf.loadCertPool(additionalCABundles...); err != nil {
+		return nil, fmt.Errorf("unable to load cert pool. Check additional CAs specified at %s and ensure the file is properly formatted: %s",
+			strings.Join(additionalCABundles, ","), err)
+	}
+
 	// TODO: Still support deprecated settings, but remove this support in future versions
 	if conf.ExternalServices.Grafana.XInClusterURL != "" {
 		conf.ExternalServices.Grafana.InternalURL = conf.ExternalServices.Grafana.XInClusterURL
@@ -1608,3 +1664,10 @@ func (config *Config) GetVersionLabelName(labels map[string]string) (string, boo
 	}
 	return "", false
 }
+
+func (c *Config) CertPool() *x509.CertPool {
+	if pool := c.Deployment.certPool; pool != nil {
+		return pool.Clone()
+	}
+	return nil
+}
diff --git a/controller/controller.go b/controller/controller.go
deleted file mode 100644
index 5322075e1..000000000
--- a/controller/controller.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package controller
-
-/*
-	The controllers manage long running tasks in Kiali that take too long
-	to be completed within a single request.
-
-	As an example, the validations controller handles validations across namespaces or meshes.
-	Namespace/mesh wide validations can take too long for a single request.
-*/
-
-import (
-	"context"
-	"fmt"
-
-	networkingv1 "istio.io/client-go/pkg/apis/networking/v1"
-	"k8s.io/apimachinery/pkg/runtime"
-	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
-	ctrl "sigs.k8s.io/controller-runtime"
-	"sigs.k8s.io/controller-runtime/pkg/log/zap"
-	metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
-
-	"github.com/kiali/kiali/business"
-	"github.com/kiali/kiali/config"
-	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
-	"github.com/kiali/kiali/log"
-)
-
-func NewScheme() (*runtime.Scheme, error) {
-	scheme := runtime.NewScheme()
-	addSchemeFuncs := []func(s *runtime.Scheme) error{
-		clientgoscheme.AddToScheme,
-		networkingv1.AddToScheme,
-	}
-
-	for _, addToScheme := range addSchemeFuncs {
-		if err := addToScheme(scheme); err != nil {
-			return nil, err
-		}
-	}
-
-	return scheme, nil
-}
-
-// Start creates and starts all the controllers. They'll get cancelled when the context is cancelled.
-func Start(ctx context.Context, conf *config.Config, cf kubernetes.ClientFactory, kialiCache cache.KialiCache, validationsService *business.IstioValidationsService) error {
-	// TODO: Replace with kiali logging but if this isn't set some errors are thrown.
-	ctrl.SetLogger(zap.New())
-
-	// Combine the istio scheme and the kube scheme.
-	log.Debug("Setting up Validations Contoller")
-	scheme, err := NewScheme()
-	if err != nil {
-		return fmt.Errorf("error setting up ValidationsController when creating scheme: %s", err)
-	}
-
-	// In the future this could be any cluster and not just home cluster.
-	homeClusterInfo := cf.GetSAHomeClusterClient().ClusterInfo()
-
-	// Create a new controller manager
-	mgr, err := ctrl.NewManager(homeClusterInfo.ClientConfig, ctrl.Options{
-		// Disable metrics server since Kiali has its own metrics server.
-		Metrics: metricsserver.Options{BindAddress: "0"},
-		Scheme:  scheme,
-	})
-	if err != nil {
-		return fmt.Errorf("error setting up ValidationsController when creating manager: %s", err)
-	}
-
-	var clusters []string
-	// We want one manager/reconciler for all clusters.
-	for _, client := range cf.GetSAClients() {
-		clusters = append(clusters, client.ClusterInfo().Name)
-	}
-
-	if err := NewValidationsController(ctx, clusters, conf, kialiCache, validationsService, mgr); err != nil {
-		return fmt.Errorf("error setting up ValidationsController: %s", err)
-	}
-
-	go func() {
-		if err := mgr.Start(ctx); err != nil {
-			log.Errorf("error starting Validations Controller: %s", err)
-		}
-		log.Debug("Stopped Validations Controller")
-	}()
-
-	return nil
-}
diff --git a/controller/validations.go b/controller/validations.go
index 0a8ebf6e9..6aa01d8e9 100644
--- a/controller/validations.go
+++ b/controller/validations.go
@@ -14,8 +14,8 @@ import (
 	ctrlsource "sigs.k8s.io/controller-runtime/pkg/source"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/models"
 )
diff --git a/grafana/grafana.go b/grafana/grafana.go
index ebbcecc05..40c26e0e2 100644
--- a/grafana/grafana.go
+++ b/grafana/grafana.go
@@ -334,6 +334,6 @@ func findDashboard(url, searchPattern string, auth *config.Auth) ([]byte, int, e
 	if len(urlParts) > 1 {
 		query = query + "&" + urlParts[1]
 	}
-	resp, code, _, err := httputil.HttpGet(query, auth, time.Second*10, nil, nil)
+	resp, code, _, err := httputil.HttpGet(query, auth, time.Second*10, nil, nil, config.Get())
 	return resp, code, err
 }
diff --git a/handlers/apps.go b/handlers/apps.go
index 40fbee520..36249e9be 100644
--- a/handlers/apps.go
+++ b/handlers/apps.go
@@ -9,11 +9,11 @@ import (
 	"github.com/gorilla/mux"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/prometheus"
diff --git a/handlers/authentication/openid_auth_controller.go b/handlers/authentication/openid_auth_controller.go
index 9d1655a90..b91cae5d1 100644
--- a/handlers/authentication/openid_auth_controller.go
+++ b/handlers/authentication/openid_auth_controller.go
@@ -22,10 +22,10 @@ import (
 	"k8s.io/client-go/tools/clientcmd/api"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/util"
 	"github.com/kiali/kiali/util/httputil"
diff --git a/handlers/authentication/token_auth_controller.go b/handlers/authentication/token_auth_controller.go
index 2c2097401..cad4a6491 100644
--- a/handlers/authentication/token_auth_controller.go
+++ b/handlers/authentication/token_auth_controller.go
@@ -11,10 +11,10 @@ import (
 	"k8s.io/client-go/tools/clientcmd/api"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/util"
 )
diff --git a/handlers/config.go b/handlers/config.go
index af9a31c49..18af14702 100644
--- a/handlers/config.go
+++ b/handlers/config.go
@@ -10,10 +10,10 @@ import (
 	"github.com/rs/zerolog"
 	"gopkg.in/yaml.v2"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/prometheus"
diff --git a/handlers/graph.go b/handlers/graph.go
index 8190e2ab7..f701b49fc 100644
--- a/handlers/graph.go
+++ b/handlers/graph.go
@@ -36,13 +36,13 @@ import (
 	"runtime/debug"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/graph"
 	"github.com/kiali/kiali/graph/api"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/prometheus"
 	"github.com/kiali/kiali/tracing"
diff --git a/handlers/istio_config.go b/handlers/istio_config.go
index 15c826f71..4eef7270a 100644
--- a/handlers/istio_config.go
+++ b/handlers/istio_config.go
@@ -10,11 +10,11 @@ import (
 	"k8s.io/apimachinery/pkg/runtime/schema"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/prometheus"
diff --git a/handlers/istio_status.go b/handlers/istio_status.go
index c5dd00247..c4a329b09 100644
--- a/handlers/istio_status.go
+++ b/handlers/istio_status.go
@@ -4,11 +4,11 @@ import (
 	"net/http"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/prometheus"
 	"github.com/kiali/kiali/tracing"
 )
diff --git a/handlers/mesh.go b/handlers/mesh.go
index 3e8be804f..eee9f6f6c 100644
--- a/handlers/mesh.go
+++ b/handlers/mesh.go
@@ -7,11 +7,11 @@ import (
 	"k8s.io/apimachinery/pkg/api/errors"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/mesh"
 	"github.com/kiali/kiali/mesh/api"
 	"github.com/kiali/kiali/models"
diff --git a/handlers/namespaces.go b/handlers/namespaces.go
index 5ccfbe473..c265da441 100644
--- a/handlers/namespaces.go
+++ b/handlers/namespaces.go
@@ -7,11 +7,11 @@ import (
 	"github.com/gorilla/mux"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/prometheus"
diff --git a/handlers/proxy_logging.go b/handlers/proxy_logging.go
index 501da2a69..5728701df 100644
--- a/handlers/proxy_logging.go
+++ b/handlers/proxy_logging.go
@@ -8,11 +8,11 @@ import (
 	"github.com/gorilla/mux"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/prometheus"
 	"github.com/kiali/kiali/tracing"
 )
diff --git a/handlers/proxy_status.go b/handlers/proxy_status.go
index 3f3a8473c..35293213a 100644
--- a/handlers/proxy_status.go
+++ b/handlers/proxy_status.go
@@ -6,10 +6,10 @@ import (
 	"github.com/gorilla/mux"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 )
 
 func ConfigDump(conf *config.Config, kialiCache cache.KialiCache, clientFactory kubernetes.ClientFactory, discovery istio.MeshDiscovery) http.HandlerFunc {
diff --git a/handlers/root.go b/handlers/root.go
index 2eecd1d08..aa5b11b69 100644
--- a/handlers/root.go
+++ b/handlers/root.go
@@ -3,10 +3,10 @@ package handlers
 import (
 	"net/http"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/status"
 )
 
diff --git a/handlers/tls.go b/handlers/tls.go
index 5b37a9f2e..1a963dd7e 100644
--- a/handlers/tls.go
+++ b/handlers/tls.go
@@ -7,11 +7,11 @@ import (
 	"github.com/gorilla/mux"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/prometheus"
diff --git a/handlers/tracing.go b/handlers/tracing.go
index 158c4b842..efbd61dc1 100644
--- a/handlers/tracing.go
+++ b/handlers/tracing.go
@@ -11,11 +11,11 @@ import (
 	"github.com/gorilla/mux"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/prometheus"
 	"github.com/kiali/kiali/tracing"
diff --git a/handlers/utils.go b/handlers/utils.go
index ea011aaf5..de66e9af5 100644
--- a/handlers/utils.go
+++ b/handlers/utils.go
@@ -10,12 +10,12 @@ import (
 	"k8s.io/client-go/tools/clientcmd/api"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/handlers/authentication"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/prometheus"
diff --git a/handlers/workloads.go b/handlers/workloads.go
index e774f59c7..2dd308a72 100644
--- a/handlers/workloads.go
+++ b/handlers/workloads.go
@@ -14,11 +14,11 @@ import (
 	"github.com/gorilla/mux"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/prometheus"
diff --git a/istio/discovery.go b/istio/discovery.go
index 1437f33d2..1abaffe2c 100644
--- a/istio/discovery.go
+++ b/istio/discovery.go
@@ -17,9 +17,9 @@ import (
 	k8syaml "k8s.io/apimachinery/pkg/util/yaml"
 	ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/observability"
diff --git a/kiali.go b/kiali.go
index 3f2f01178..623ac9d1d 100644
--- a/kiali.go
+++ b/kiali.go
@@ -62,12 +62,12 @@ import (
 	k8snetworkingv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/controller"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/prometheus"
diff --git a/kubernetes/client.go b/kubernetes/client.go
index b159abe5a..cb44afc3f 100644
--- a/kubernetes/client.go
+++ b/kubernetes/client.go
@@ -15,7 +15,6 @@ import (
 	kube "k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/rest"
 	"k8s.io/client-go/tools/clientcmd"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 	ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
 	gatewayapiclient "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned"
 
@@ -89,7 +88,7 @@ type K8SClient struct {
 	k8s   kube.Interface
 
 	// controller runtime client. This is only embedded to make the transition to controller-runtime easier.
-	client.Reader
+	ctrlclient.Reader
 
 	projectClient projectclient.Interface
 	routeClient   routeclient.Interface
@@ -119,6 +118,8 @@ type K8SClient struct {
 
 	// Separated out for testing purposes
 	getPodPortForwarderFunc func(namespace, name, portMap string) (httputil.PortForwarder, error)
+
+	conf *kialiconfig.Config
 }
 
 // Ensure the K8SClient implements the full read-write UserClientInterface
@@ -191,6 +192,7 @@ func getConfigForLocalCluster() (*rest.Config, error) {
 func newClientFromConfig(config *rest.Config) (*K8SClient, error) {
 	client := K8SClient{
 		token: config.BearerToken,
+		conf:  kialiconfig.Get(),
 	}
 
 	log.Debugf("Rest perf config QPS: %f Burst: %d", config.QPS, config.Burst)
@@ -252,7 +254,7 @@ func NewClient(
 	routeClient routeclient.Interface,
 	userClient userclient.Interface,
 	oAuthClient oauthclient.Interface,
-	reader client.Reader,
+	reader ctrlclient.Reader,
 ) *K8SClient {
 	return &K8SClient{
 		istioClientset: istioClient,
diff --git a/kubernetes/istio.go b/kubernetes/istio.go
index d0f5660ea..7fc99fb4b 100644
--- a/kubernetes/istio.go
+++ b/kubernetes/istio.go
@@ -136,7 +136,7 @@ func (in *K8SClient) SetProxyLogLevel(namespace, pod, level string) error {
 
 	// Ready to create a request
 	url := fmt.Sprintf("http://localhost:%d%s", localPort, path)
-	body, code, _, err := httputil.HttpPost(url, nil, nil, time.Second*10, nil)
+	body, code, _, err := httputil.HttpPost(url, nil, nil, time.Second*10, nil, in.conf)
 	if code >= 400 {
 		log.Errorf("Error whilst posting. Error: %s. Body: %s", err, string(body))
 		return fmt.Errorf("error sending post request %s from %s/%s. Response code: %d", path, namespace, pod, code)
diff --git a/kubernetes/kubernetes.go b/kubernetes/kubernetes.go
index 17e55e18d..84ffcc714 100644
--- a/kubernetes/kubernetes.go
+++ b/kubernetes/kubernetes.go
@@ -103,7 +103,7 @@ func (in *K8SClient) ForwardGetRequest(namespace, podName string, destinationPor
 	defer f.Stop()
 
 	// Ready to create a request
-	resp, code, _, err := httputil.HttpGet(fmt.Sprintf("http://localhost:%d%s", localPort, path), nil, 10*time.Second, nil, nil)
+	resp, code, _, err := httputil.HttpGet(fmt.Sprintf("http://localhost:%d%s", localPort, path), nil, 10*time.Second, nil, nil, in.conf)
 	if code >= 400 {
 		return resp, fmt.Errorf("error fetching %s from %s/%s. Response code: %d", path, namespace, podName, code)
 	}
diff --git a/mesh/api/api.go b/mesh/api/api.go
index 71e77930b..48b5ceda5 100644
--- a/mesh/api/api.go
+++ b/mesh/api/api.go
@@ -8,12 +8,12 @@ import (
 	"k8s.io/apimachinery/pkg/api/errors"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/graph"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/mesh"
 	"github.com/kiali/kiali/mesh/config/common"
diff --git a/mesh/appender.go b/mesh/appender.go
index f176e9701..8c105944e 100644
--- a/mesh/appender.go
+++ b/mesh/appender.go
@@ -4,11 +4,11 @@ import (
 	"context"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/prometheus"
 )
 
diff --git a/mesh/util.go b/mesh/util.go
index 32a497172..6b8344a48 100644
--- a/mesh/util.go
+++ b/mesh/util.go
@@ -4,10 +4,10 @@ import (
 	"context"
 	nethttp "net/http"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/status"
 )
 
diff --git a/prometheus/client.go b/prometheus/client.go
index b9b5e29af..351b3de42 100644
--- a/prometheus/client.go
+++ b/prometheus/client.go
@@ -68,12 +68,13 @@ func initPromCache(ctx context.Context) {
 // NewClient creates a new client to the Prometheus API.
 // It returns an error on any problem.
 func NewClient() (*Client, error) {
-	return NewClientForConfig(config.Get().ExternalServices.Prometheus)
+	return NewClientForConfig(*config.Get())
 }
 
 // NewClient creates a new client to the Prometheus API.
 // It returns an error on any problem.
-func NewClientForConfig(cfg config.PrometheusConfig) (*Client, error) {
+func NewClientForConfig(conf config.Config) (*Client, error) {
+	cfg := conf.ExternalServices.Prometheus
 	clientConfig := api.Config{Address: cfg.URL}
 
 	// Prom Cache will be initialized once at first use of Prometheus Client
@@ -113,7 +114,7 @@ func NewClientForConfig(cfg config.PrometheusConfig) (*Client, error) {
 		TLSHandshakeTimeout: 10 * time.Second,
 	}
 
-	transportConfig, err := httputil.CreateTransport(&auth, roundTripper, httputil.DefaultTimeout, cfg.CustomHeaders)
+	transportConfig, err := httputil.CreateTransport(&conf, &auth, roundTripper, httputil.DefaultTimeout, cfg.CustomHeaders)
 	if err != nil {
 		return nil, err
 	}
diff --git a/routing/router.go b/routing/router.go
index 9f196e7c4..e5d9cfba6 100644
--- a/routing/router.go
+++ b/routing/router.go
@@ -16,13 +16,13 @@ import (
 	zerolog "github.com/rs/zerolog/log"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/handlers"
 	"github.com/kiali/kiali/handlers/authentication"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	kialiprometheus "github.com/kiali/kiali/prometheus"
 	"github.com/kiali/kiali/prometheus/internalmetrics"
@@ -357,17 +357,38 @@ func (a alice) append(m func(http.Handler) http.Handler) alice {
 	a.m = append(a.m, m)
 	return a
 }
+
 func (a alice) then(h http.Handler) http.Handler {
 	for i := range a.m {
 		h = a.m[len(a.m)-1-i](h)
 	}
 	return h
 }
+
 func buildHttpHandlerLogger(route Route, handlerFunction http.Handler) http.Handler {
 	c := alice{}
 	c = c.append(hlog.NewHandler(zerolog.With().Str("route", route.Name).Logger()))
-	c = c.append(hlog.HostHandler("Host", true))
-	c = c.append(hlog.RequestIDHandler("RequestID", "Request-Id"))
+
+	// TODO: commenting out but leaving these here in case we want to look into including them at a future date
+	// c = c.append(hlog.HostHandler("host", true))
+	// if log.IsTrace() {
+	// 	c = c.append(hlog.RemoteAddrHandler("remote-addr"))
+	// }
+
+	// extract and log the request ID - if we have a X-Request-Id header we use it; otherwise, we generate our own
+	xRequestIdHeader := "X-Request-Id"
+	xRequestFieldKey := "request-id"
+	c = c.append(func(next http.Handler) http.Handler {
+		requestIDGeneratorHandler := hlog.RequestIDHandler(xRequestFieldKey, "")
+		customHeaderHandler := hlog.CustomHeaderHandler(xRequestFieldKey, xRequestIdHeader)
+		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+			if r.Header.Get(xRequestIdHeader) == "" {
+				requestIDGeneratorHandler(next).ServeHTTP(w, r)
+			} else {
+				customHeaderHandler(next).ServeHTTP(w, r)
+			}
+		})
+	})
 
 	return c.then(handlerFunction)
 }
diff --git a/routing/routes.go b/routing/routes.go
index 9d79150fa..7e2a5123c 100644
--- a/routing/routes.go
+++ b/routing/routes.go
@@ -6,13 +6,13 @@ import (
 	"golang.org/x/exp/maps"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/handlers"
 	"github.com/kiali/kiali/handlers/authentication"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/prometheus"
 	"github.com/kiali/kiali/tracing"
 )
diff --git a/server/server.go b/server/server.go
index ed7bb87a1..6af82b046 100644
--- a/server/server.go
+++ b/server/server.go
@@ -12,11 +12,11 @@ import (
 	sdktrace "go.opentelemetry.io/otel/sdk/trace"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/log"
 	"github.com/kiali/kiali/observability"
 	"github.com/kiali/kiali/prometheus"
diff --git a/status/status.go b/status/status.go
index 513e7039d..92900113b 100644
--- a/status/status.go
+++ b/status/status.go
@@ -5,10 +5,10 @@ import (
 	"context"
 	"strings"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/models"
 )
 
diff --git a/status/versions.go b/status/versions.go
index 1b551d028..afa3949eb 100644
--- a/status/versions.go
+++ b/status/versions.go
@@ -27,7 +27,7 @@ func getVersions(ctx context.Context, conf *config.Config, clientFactory kuberne
 	}
 
 	if conf.ExternalServices.Grafana.Enabled && grafana != nil {
-		gv, err := grafanaVersion(ctx, grafana, conf.ExternalServices.Grafana, clientFactory.GetSAHomeClusterClient())
+		gv, err := grafanaVersion(ctx, grafana, conf, clientFactory.GetSAHomeClusterClient())
 		if err != nil {
 			log.Infof("Error getting Grafana version: %v", err)
 		} else {
@@ -109,7 +109,7 @@ func tracingVersion(conf *config.Config, homeClusterSAClient kubernetes.ClientIn
 				}
 			}
 
-			body, statusCode, _, err := httputil.HttpGet(versionUrl, &auth, 10*time.Second, nil, nil)
+			body, statusCode, _, err := httputil.HttpGet(versionUrl, &auth, 10*time.Second, nil, nil, conf)
 			if err != nil || statusCode > 399 {
 				log.Infof("jaeger version check failed: url=[%v], code=[%v], err=[%v]", versionUrl, statusCode, err)
 			} else {
@@ -130,7 +130,7 @@ func tracingVersion(conf *config.Config, homeClusterSAClient kubernetes.ClientIn
 		} else {
 			// Tempo
 			if tracingConfig.Provider == config.TempoProvider {
-				body, statusCode, _, err := httputil.HttpGet(fmt.Sprintf("%s/api/status/buildinfo", versionUrl), &tracingConfig.Auth, 10*time.Second, nil, nil)
+				body, statusCode, _, err := httputil.HttpGet(fmt.Sprintf("%s/api/status/buildinfo", versionUrl), &tracingConfig.Auth, 10*time.Second, nil, nil, conf)
 				if err != nil || statusCode > 399 {
 					log.Infof("tempo version check failed: url=[%v], code=[%v], err=[%v]", versionUrl, statusCode, err)
 				} else {
@@ -157,7 +157,7 @@ type grafanaResponseVersion struct {
 	BuildInfo grafanaBuildInfo `json:"buildInfo"`
 }
 
-func grafanaVersion(ctx context.Context, grafana *grafana.Service, grafanaConfig config.GrafanaConfig, homeClusterSAClient kubernetes.ClientInterface) (*models.ExternalServiceInfo, error) {
+func grafanaVersion(ctx context.Context, grafana *grafana.Service, conf *config.Config, homeClusterSAClient kubernetes.ClientInterface) (*models.ExternalServiceInfo, error) {
 	product := models.ExternalServiceInfo{}
 	product.Name = "Grafana"
 	product.Url = grafana.URL(ctx)
@@ -165,11 +165,11 @@ func grafanaVersion(ctx context.Context, grafana *grafana.Service, grafanaConfig
 	versionUrl := grafana.VersionURL(ctx)
 	if versionUrl != "" {
 		// Be sure to copy config.Auth and not modify the existing
-		auth := grafanaConfig.Auth
+		auth := conf.ExternalServices.Grafana.Auth
 		if auth.UseKialiToken {
 			auth.Token = homeClusterSAClient.GetToken()
 		}
-		body, statusCode, _, err := httputil.HttpGet(versionUrl, &auth, 10*time.Second, nil, nil)
+		body, statusCode, _, err := httputil.HttpGet(versionUrl, &auth, 10*time.Second, nil, nil, conf)
 
 		if err != nil || statusCode > 399 {
 			log.Infof("grafana version check failed: url=[%v], code=[%v]", versionUrl, statusCode)
@@ -197,7 +197,7 @@ func prometheusVersion(conf *config.Config, homeClusterSAClient kubernetes.Clien
 	}
 
 	// see https://prometheus.io/docs/prometheus/latest/querying/api/#build-information
-	body, _, _, err := httputil.HttpGet(cfg.URL+"/api/v1/status/buildinfo", &auth, 10*time.Second, nil, nil)
+	body, _, _, err := httputil.HttpGet(cfg.URL+"/api/v1/status/buildinfo", &auth, 10*time.Second, nil, nil, conf)
 	if err == nil {
 		err = json.Unmarshal(body, &prometheusV)
 		if err == nil {
diff --git a/tracing/client.go b/tracing/client.go
index 091c80ba5..431dc75fc 100644
--- a/tracing/client.go
+++ b/tracing/client.go
@@ -129,7 +129,7 @@ func newClient(ctx context.Context, conf *config.Config, token string) (*Client,
 		p, _ := net.LookupPort("tcp", u.Scheme)
 		port = strconv.Itoa(p)
 	}
-	opts, err := grpcutil.GetAuthDialOptions(u.Scheme == "https", &auth)
+	opts, err := grpcutil.GetAuthDialOptions(conf, u.Scheme == "https", &auth)
 	if err != nil {
 		log.Errorf("Error while building GRPC dial options: %v", err)
 		return nil, err
@@ -173,7 +173,7 @@ func newClient(ctx context.Context, conf *config.Config, token string) (*Client,
 		// Legacy HTTP client
 		log.Tracef("Using legacy HTTP client for Tracing: url=%v, auth.type=%s", u, auth.Type)
 		timeout := time.Duration(config.Get().ExternalServices.Tracing.QueryTimeout) * time.Second
-		transport, err := httputil.CreateTransport(&auth, &http.Transport{}, timeout, cfgTracing.CustomHeaders)
+		transport, err := httputil.CreateTransport(conf, &auth, &http.Transport{}, timeout, cfgTracing.CustomHeaders)
 		if err != nil {
 			return nil, err
 		}
diff --git a/util/grpcutil/grpc_util.go b/util/grpcutil/grpc_util.go
index b1632efba..a32a0df5c 100644
--- a/util/grpcutil/grpc_util.go
+++ b/util/grpcutil/grpc_util.go
@@ -26,13 +26,13 @@ func (c perRPCCredentials) RequireTransportSecurity() bool {
 	return c.requireSecurity
 }
 
-func GetAuthDialOptions(tls bool, auth *config.Auth) ([]grpc.DialOption, error) {
+func GetAuthDialOptions(conf *config.Config, tls bool, auth *config.Auth) ([]grpc.DialOption, error) {
 	if auth == nil {
 		return []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}, nil
 	}
 	var opts []grpc.DialOption
 	if tls {
-		tlscfg, err := httputil.GetTLSConfig(auth)
+		tlscfg, err := httputil.GetTLSConfig(conf, auth)
 		if err != nil {
 			return nil, err
 		}
diff --git a/util/httputil/http_util.go b/util/httputil/http_util.go
index f6a10a222..22f0383a5 100644
--- a/util/httputil/http_util.go
+++ b/util/httputil/http_util.go
@@ -2,7 +2,6 @@ package httputil
 
 import (
 	"crypto/tls"
-	"crypto/x509"
 	"encoding/base64"
 	"fmt"
 	"io"
@@ -26,7 +25,7 @@ func HttpMethods() []string {
 	}
 }
 
-func HttpGet(url string, auth *config.Auth, timeout time.Duration, customHeaders map[string]string, cookies []*http.Cookie) ([]byte, int, []*http.Cookie, error) {
+func HttpGet(url string, auth *config.Auth, timeout time.Duration, customHeaders map[string]string, cookies []*http.Cookie, conf *config.Config) ([]byte, int, []*http.Cookie, error) {
 	req, err := http.NewRequest(http.MethodGet, url, nil)
 	if err != nil {
 		return nil, 0, nil, err
@@ -36,7 +35,7 @@ func HttpGet(url string, auth *config.Auth, timeout time.Duration, customHeaders
 		req.AddCookie(c)
 	}
 
-	transport, err := CreateTransport(auth, &http.Transport{}, timeout, customHeaders)
+	transport, err := CreateTransport(conf, auth, &http.Transport{}, timeout, customHeaders)
 	if err != nil {
 		return nil, 0, nil, err
 	}
@@ -53,13 +52,13 @@ func HttpGet(url string, auth *config.Auth, timeout time.Duration, customHeaders
 }
 
 // HttpPost sends an HTTP Post request to the given URL and returns the response body.
-func HttpPost(url string, auth *config.Auth, body io.Reader, timeout time.Duration, customHeaders map[string]string) ([]byte, int, []*http.Cookie, error) {
+func HttpPost(url string, auth *config.Auth, body io.Reader, timeout time.Duration, customHeaders map[string]string, conf *config.Config) ([]byte, int, []*http.Cookie, error) {
 	req, err := http.NewRequest(http.MethodPost, url, body)
 	if err != nil {
 		return nil, 0, nil, err
 	}
 
-	transport, err := CreateTransport(auth, &http.Transport{}, timeout, customHeaders)
+	transport, err := CreateTransport(conf, auth, &http.Transport{}, timeout, customHeaders)
 	if err != nil {
 		return nil, 0, nil, err
 	}
@@ -128,7 +127,7 @@ func newCustomHeadersRoundTripper(headers map[string]string, rt http.RoundTrippe
 // idle connections stay open for as long as 2 * timeout. This should only be
 // done in cases where you know the request is very likely going to be reused at
 // some point in the near future.
-func CreateTransport(auth *config.Auth, transportConfig *http.Transport, timeout time.Duration, customHeaders map[string]string) (http.RoundTripper, error) {
+func CreateTransport(conf *config.Config, auth *config.Auth, transportConfig *http.Transport, timeout time.Duration, customHeaders map[string]string) (http.RoundTripper, error) {
 	// Limits the time spent establishing a TCP connection if a new one is
 	// needed. If DialContext is not set, Dial is used, we only create a new one
 	// if neither is defined.
@@ -145,7 +144,7 @@ func CreateTransport(auth *config.Auth, transportConfig *http.Transport, timeout
 	outerRoundTripper := newCustomHeadersRoundTripper(customHeaders, transportConfig)
 
 	if auth != nil {
-		tlscfg, err := GetTLSConfig(auth)
+		tlscfg, err := GetTLSConfig(conf, auth)
 		if err != nil {
 			return nil, err
 		}
@@ -158,11 +157,10 @@ func CreateTransport(auth *config.Auth, transportConfig *http.Transport, timeout
 	return outerRoundTripper, nil
 }
 
-func GetTLSConfig(auth *config.Auth) (*tls.Config, error) {
+func GetTLSConfig(conf *config.Config, auth *config.Auth) (*tls.Config, error) {
 	if auth.InsecureSkipVerify || auth.CAFile != "" {
-		var certPool *x509.CertPool
+		certPool := conf.CertPool()
 		if auth.CAFile != "" {
-			certPool = x509.NewCertPool()
 			cert, err := os.ReadFile(auth.CAFile)
 			if err != nil {
 				return nil, fmt.Errorf("failed to get root CA certificates: %s", err)
diff --git a/util/intutil/convert.go b/util/intutil/convert.go
deleted file mode 100644
index abaa74675..000000000
--- a/util/intutil/convert.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package intutil
-
-import "errors"
-
-func Convert(subject interface{}) (int, error) {
-	var result int
-
-	switch typedSubject := subject.(type) {
-	case uint64:
-		result = int(typedSubject)
-	case int64:
-		result = int(typedSubject)
-	case int32:
-		result = int(typedSubject)
-	case uint32:
-		result = int(typedSubject)
-	case int:
-		result = typedSubject
-	default:
-		return 0, errors.New("it is not a numeric input")
-	}
-
-	return result, nil
-}



Test patch:
diff --git a/business/controlplane_monitor_test.go b/business/controlplane_monitor_test.go
index a73fb5831..c7285f2ff 100644
--- a/business/controlplane_monitor_test.go
+++ b/business/controlplane_monitor_test.go
@@ -15,10 +15,10 @@ import (
 	core_v1 "k8s.io/api/core/v1"
 	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 )
 
diff --git a/business/health_test.go b/business/health_test.go
index 8f6eab59e..d6e67ce03 100644
--- a/business/health_test.go
+++ b/business/health_test.go
@@ -15,10 +15,10 @@ import (
 	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/prometheus/prometheustest"
diff --git a/business/namespaces_test.go b/business/namespaces_test.go
index 1b3060dc1..4bb3c745e 100644
--- a/business/namespaces_test.go
+++ b/business/namespaces_test.go
@@ -16,10 +16,10 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 	kubeclienttesting "k8s.io/client-go/testing"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/models"
 )
diff --git a/business/services_test.go b/business/services_test.go
index 211947c19..2e2e54fb0 100644
--- a/business/services_test.go
+++ b/business/services_test.go
@@ -18,10 +18,10 @@ import (
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/util/yaml"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/prometheus"
diff --git a/business/testing.go b/business/testing.go
index 69ffe6138..30a4d9f90 100644
--- a/business/testing.go
+++ b/business/testing.go
@@ -8,10 +8,10 @@ package business
 import (
 	"testing"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/prometheus"
 )
diff --git a/business/workloads_test.go b/business/workloads_test.go
index c2ab6b28e..9f44f7f3a 100644
--- a/business/workloads_test.go
+++ b/business/workloads_test.go
@@ -20,9 +20,9 @@ import (
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/types"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/prometheus/prometheustest"
diff --git a/kubernetes/cache/cache_test.go b/cache/cache_test.go
similarity index 99%
rename from kubernetes/cache/cache_test.go
rename to cache/cache_test.go
index b8e904469..db68f8642 100644
--- a/kubernetes/cache/cache_test.go
+++ b/cache/cache_test.go
@@ -14,9 +14,9 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 	ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/models"
 )
@@ -303,7 +303,7 @@ func TestZtunnelDump(t *testing.T) {
 	initData := cache.GetZtunnelDump("cluster-default", "istio-system", "ztunnel-7hml8")
 	require.Nil(initData)
 
-	zTunnelData, err := os.Open("../testdata/ztunnel-config.json")
+	zTunnelData, err := os.Open("../kubernetes/testdata/ztunnel-config.json")
 	require.NoError(err)
 	defer zTunnelData.Close()
 
diff --git a/kubernetes/cache/testing.go b/cache/testing.go
similarity index 100%
rename from kubernetes/cache/testing.go
rename to cache/testing.go
diff --git a/kubernetes/cache/transform_test.go b/cache/transform_test.go
similarity index 98%
rename from kubernetes/cache/transform_test.go
rename to cache/transform_test.go
index 235f63602..5e673d8bf 100644
--- a/kubernetes/cache/transform_test.go
+++ b/cache/transform_test.go
@@ -8,8 +8,8 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 )
 
 func TestGetPodTrimmed(t *testing.T) {
diff --git a/config/config_test.go b/config/config_test.go
index 9491b5140..a690810cb 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -1,6 +1,8 @@
 package config
 
 import (
+	"crypto/x509"
+	_ "embed"
 	"fmt"
 	"math/rand"
 	"os"
@@ -14,8 +16,12 @@ import (
 	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	"github.com/kiali/kiali/util"
+	"github.com/kiali/kiali/util/filetest"
 )
 
+//go:embed testdata/test-ca.pem
+var testCA []byte
+
 func TestSecretFileOverrides(t *testing.T) {
 	// create a mock volume mount directory where the test secret content will go
 	overrideSecretsDir = t.TempDir()
@@ -36,8 +42,11 @@ func TestSecretFileOverrides(t *testing.T) {
 	conf.ExternalServices.CustomDashboards.Prometheus.Auth.Token = "cd-prometheustoken"
 
 	// Unmarshal will override settings found in env vars (if there are any env vars)
-	yamlString, _ := Marshal(conf)
-	conf, _ = Unmarshal(yamlString)
+	var err error
+	yamlString, err := Marshal(conf)
+	require.NoError(t, err)
+	conf, err = Unmarshal(yamlString)
+	require.NoError(t, err)
 
 	// we don't have the files yet - so nothing should be overridden from the original yaml
 	assert.Equal(t, conf.ExternalServices.Grafana.Auth.Username, "grafanausername")
@@ -749,3 +758,59 @@ func TestExtractAccessibleNamespaceList(t *testing.T) {
 		})
 	}
 }
+
+func TestLoadingCertPool(t *testing.T) {
+	systemPool, err := x509.SystemCertPool()
+	require.NoError(t, err)
+
+	addtionalCAPool := systemPool.Clone()
+	require.True(t, addtionalCAPool.AppendCertsFromPEM(testCA), "unable to add testCA to system pool")
+
+	invalidCA := filetest.TempFile(t, []byte("notarealCA")).Name()
+
+	cases := map[string]struct {
+		addtionalBundles []string
+		expected         *x509.CertPool
+		expectedErr      bool
+	}{
+		"No addtional CAs loads system Pool": {
+			expected: systemPool.Clone(),
+		},
+		"Addtional CAs loads system Pool": {
+			addtionalBundles: []string{"testdata/test-ca.pem"},
+			expected:         addtionalCAPool,
+		},
+		"Non-existant CA file does not return err and still loads system pool": {
+			addtionalBundles: []string{"non-existant"},
+			expected:         systemPool.Clone(),
+		},
+		"CA file with bogus contents returns err and still loads system pool": {
+			addtionalBundles: []string{invalidCA},
+			expected:         systemPool.Clone(),
+			expectedErr:      true,
+		},
+		// Need to test this for OpenShift serving cert that may come from multiple places.
+		"Loading the same CA multiple times": {
+			addtionalBundles: []string{"testdata/test-ca.pem", "testdata/test-ca.pem"},
+			expected:         addtionalCAPool,
+		},
+	}
+	for name, tc := range cases {
+		t.Run(name, func(t *testing.T) {
+			require := require.New(t)
+
+			conf := NewConfig()
+
+			err = conf.loadCertPool(tc.addtionalBundles...)
+			if tc.expectedErr {
+				require.Error(err)
+			} else {
+				require.NoError(err)
+			}
+
+			actual := conf.CertPool()
+
+			require.True(tc.expected.Equal(actual))
+		})
+	}
+}
diff --git a/config/testdata/test-ca.pem b/config/testdata/test-ca.pem
new file mode 100644
index 000000000..ee1fd5ff6
--- /dev/null
+++ b/config/testdata/test-ca.pem
@@ -0,0 +1,33 @@
+-----BEGIN CERTIFICATE-----
+MIIFpzCCA4+gAwIBAgIUO7QaUS9mDCIH6AKCP34n88n3LpswDQYJKoZIhvcNAQEL
+BQAwYzELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB05vd2hlcmUxEjAQBgNVBAcMCVNv
+bWV3aGVyZTEOMAwGA1UECgwFS2lhbGkxDjAMBgNVBAsMBUtpYWxpMQ4wDAYDVQQD
+DAVraWFsaTAeFw0yNTA1MTIxOTE0MDlaFw0zNTA1MTAxOTE0MDlaMGMxCzAJBgNV
+BAYTAlVTMRAwDgYDVQQIDAdOb3doZXJlMRIwEAYDVQQHDAlTb21ld2hlcmUxDjAM
+BgNVBAoMBUtpYWxpMQ4wDAYDVQQLDAVLaWFsaTEOMAwGA1UEAwwFa2lhbGkwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnKvr31ubb2gMIFxfqc5EnsSNw
+aTPSBX1d5wgNOcJ+MIfVcF044qFiDpi9Zy9R+VydxB+mlPww8iUPy63VjatlsrFD
+QhDZgEbc0L8bpLrGTBGR80TIpsgkhMkB+zqKbm1SAQthAZEAAp1U5jXRV33FWx6y
+zsAQSjZRJ4AXIrUX7TkVoZL4dyBeDpUI6aR/fJZoK3ryRhveqxcxN7a0z9W7vERE
+FXd0d31+43gP2cJOdevYj0e7NaNBdpnR4Hf0Y/Rw9hVihrrInbiKEOfl6jz4EdBg
+hHQ0efZPSuZgM27Y46JYz8NkBSV8rp/et+zjiaoFrZoAQD1JQL5Je3O47XjhaeLz
+iLg5cq9cRoHYYLZWq64ddCDbdC7nfQGAw9oIDYCRTKrSQBGH76vbrW8jHaykoLSL
+jvPFw+niogNfioApWJn967eIZYKI7VPY5ifzKglhHhq4QDfyExNxDRnFKsj4Oezf
+5ePfez56Q/KIzGE7ffH/aDjsoYb2mt+O7a+X5V63XYtMnkuot6rIwDx8P84lbMT0
+vILHQ2OyByWou0qs5WtEKIOthc47AWrpgbXQOR+yPHEOlnTGMUSICcPh3csATPQK
+a/Iuami4fTUojZTiUo0/0nHxpzSmaa9APx7gifZTPD6kTL4+9rRma+yAsLw4QAj/
+18KrUEWy7vWaaSn01wIDAQABo1MwUTAdBgNVHQ4EFgQUe4A63Qq6QFGpJMl/MNwR
+sEBvlJMwHwYDVR0jBBgwFoAUe4A63Qq6QFGpJMl/MNwRsEBvlJMwDwYDVR0TAQH/
+BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAVDOyU7VoRO/za9JT9MoEpK7tl/eS
+oJZsLFsbg8f0Vh1Fl18u5QfJLgRe0hegxFGS8vVcfDk90E9Y2N/7dqN/RHwkPygi
+AETDz3tiwYtixFBvWGPY1o4RF1kL2bndL4rGulKharp3gHuC7tIrUbZ7qC4TJtQ4
+bCq+XzpZvzff/ZMwU6PfcZMTPI6sSIkQ3Cq8n4suf+F36jvFEZf7gKTDFlbFRyG+
+WpWmzrr0wTJmfzwIP2f9z4V+q20nUbhtRAwyeqUlLfbVWqOBnOY00OkLxNYa3H3Y
+l2uWApLao3f0M/Ld0hGPBTpDca7t9AheslZQK11w1S/8+s0QhFUen4371CpIrV9B
+GhNFUxkqQ/eVMnAOHUASGuT5Exwp9BihSukqk/DDLX8E6OBzvu8uG+M+5jf+U+dG
+h6tOAp9DCZVd5xeLGOlcEHKyTqUwM4lrR0rZpAzf/jcRbw13JSXlWDEl9ivI8EeX
+8YkVYDO8C6g1veYx9Z9lf8qLy8/7sir8Qwypbj8w2IJjNpW1GjgMu3jxH37ZMB7O
+ImmtTGFpt/4fb++rfstHyIf4YcbBTV0wGfx44BEr2hQ2Mct7FZKZ0W0t1XtRakGu
+KFF1Iso1l61TaL54fSw7mD64TNx6CAwZ+qAWSbCFb+qP+ASiQGuqxjqFmYUVkupp
+Vlw4URslP3x7hUA=
+-----END CERTIFICATE-----
diff --git a/controller/validations_test.go b/controller/validations_test.go
index f6c2c6f78..2fe0b2310 100644
--- a/controller/validations_test.go
+++ b/controller/validations_test.go
@@ -19,11 +19,11 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/reconcile"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/controller"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/store"
diff --git a/graph/api/api_test.go b/graph/api/api_test.go
index 8d586b07a..6569af1a2 100644
--- a/graph/api/api_test.go
+++ b/graph/api/api_test.go
@@ -22,11 +22,11 @@ import (
 	"k8s.io/client-go/tools/clientcmd/api"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/graph"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/prometheus"
 	"github.com/kiali/kiali/prometheus/prometheustest"
@@ -1200,7 +1200,7 @@ func respond(w http.ResponseWriter, code int, payload interface{}) {
 func assertObjectsEqual(t *testing.T, expected, actual []byte, expectedFileName string) {
 	if !assert.ObjectsAreEqual(expected, actual) {
 		// uncomment this if you are trying to create new versions of the expected files, in case of an impl change
-		//os.WriteFile(expectedFileName, actual, 0o644)
+		// os.WriteFile(expectedFileName, actual, 0o644)
 
 		t.Logf("Actual response does not equal expected golden copy [%s]. If you've updated the golden copy, ensure it ends with a newline.", expectedFileName)
 		t.Fail()
@@ -3871,45 +3871,53 @@ func ambientWorkloads(t *testing.T) *business.Layer {
 			Name:        "productpage-v1",
 			Namespace:   "bookinfo",
 			Labels:      map[string]string{"app": "productpage", "version": "v1"},
-			Annotations: map[string]string{"sidecar.istio.io/status": "{\"version\":\"\",\"initContainers\":[\"istio-init\",\"enable-core-dump\"],\"containers\":[\"istio-proxy\"],\"volumes\":[\"istio-envoy\",\"istio-certs\"]}"}},
+			Annotations: map[string]string{"sidecar.istio.io/status": "{\"version\":\"\",\"initContainers\":[\"istio-init\",\"enable-core-dump\"],\"containers\":[\"istio-proxy\"],\"volumes\":[\"istio-envoy\",\"istio-certs\"]}"},
+		},
 		Spec: core_v1.PodSpec{
 			Containers: []core_v1.Container{
 				{Name: "productpage-v1", Image: "whatever"},
 			},
-		}}
+		},
+	}
 	k8spod2 := &core_v1.Pod{
 		ObjectMeta: meta_v1.ObjectMeta{
 			Name:        "ratings-v1",
 			Namespace:   "bookinfo",
 			Labels:      map[string]string{"app": "ratings", "version": "v1"},
-			Annotations: map[string]string{"sidecar.istio.io/status": "{\"version\":\"\",\"initContainers\":[\"istio-init\",\"enable-core-dump\"],\"containers\":[\"istio-proxy\"],\"volumes\":[\"istio-envoy\",\"istio-certs\"]}"}},
+			Annotations: map[string]string{"sidecar.istio.io/status": "{\"version\":\"\",\"initContainers\":[\"istio-init\",\"enable-core-dump\"],\"containers\":[\"istio-proxy\"],\"volumes\":[\"istio-envoy\",\"istio-certs\"]}"},
+		},
 		Spec: core_v1.PodSpec{
 			Containers: []core_v1.Container{
 				{Name: "ratings-v1", Image: "whatever"},
 			},
-		}}
+		},
+	}
 	k8spod3 := &core_v1.Pod{
 		ObjectMeta: meta_v1.ObjectMeta{
 			Name:        "reviews-v1",
 			Namespace:   "bookinfo",
 			Labels:      map[string]string{"app": "reviews", "version": "v1"},
-			Annotations: map[string]string{"sidecar.istio.io/status": "{\"version\":\"\",\"initContainers\":[\"istio-init\",\"enable-core-dump\"],\"containers\":[\"istio-proxy\"],\"volumes\":[\"istio-envoy\",\"istio-certs\"]}"}},
+			Annotations: map[string]string{"sidecar.istio.io/status": "{\"version\":\"\",\"initContainers\":[\"istio-init\",\"enable-core-dump\"],\"containers\":[\"istio-proxy\"],\"volumes\":[\"istio-envoy\",\"istio-certs\"]}"},
+		},
 		Spec: core_v1.PodSpec{
 			Containers: []core_v1.Container{
 				{Name: "reviews-v1", Image: "whatever"},
 			},
-		}}
+		},
+	}
 	k8spod4 := &core_v1.Pod{
 		ObjectMeta: meta_v1.ObjectMeta{
 			Name:        "waypoint",
 			Namespace:   "bookinfo",
 			Labels:      map[string]string{"app": "waypoint", "version": "v1", config.WaypointLabel: config.WaypointLabelValue, config.GatewayLabel: "waypoint"},
-			Annotations: map[string]string{"sidecar.istio.io/status": "{\"version\":\"\",\"initContainers\":[\"istio-init\",\"enable-core-dump\"],\"containers\":[\"istio-proxy\"],\"volumes\":[\"istio-envoy\",\"istio-certs\"]}"}},
+			Annotations: map[string]string{"sidecar.istio.io/status": "{\"version\":\"\",\"initContainers\":[\"istio-init\",\"enable-core-dump\"],\"containers\":[\"istio-proxy\"],\"volumes\":[\"istio-envoy\",\"istio-certs\"]}"},
+		},
 		Spec: core_v1.PodSpec{
 			Containers: []core_v1.Container{
 				{Name: "istio-waypoint", Image: "whatever"},
 			},
-		}}
+		},
+	}
 
 	ns := kubetest.FakeNamespaceWithLabels("bookinfo", map[string]string{"istio.io/dataplane-mode": "ambient"})
 	k8s := kubetest.NewFakeK8sClient(k8spod1, k8spod2, k8spod3, k8spod4, ns)
@@ -3926,7 +3934,6 @@ func ambientWorkloads(t *testing.T) *business.Layer {
 }
 
 func ambientMockGraph(api *prometheustest.PromAPIMock) {
-
 	q0 := `round(sum(rate(istio_requests_total{reporter=~"waypoint|source",source_workload_namespace!="bookinfo",destination_workload_namespace="unknown",destination_workload="unknown",destination_service=~"^.+\\.bookinfo\\..+$"} [600s])) by (source_cluster,source_workload_namespace,source_workload,source_canonical_service,source_canonical_revision,destination_cluster,destination_service_namespace,destination_service,destination_service_name,destination_workload_namespace,destination_workload,destination_canonical_service,destination_canonical_revision,request_protocol,response_code,grpc_response_status,response_flags) > 0,0.001)`
 	v0 := model.Vector{}
 
diff --git a/graph/telemetry/istio/appender/extensions_test.go b/graph/telemetry/istio/appender/extensions_test.go
index d91dee8eb..7db0c48a5 100644
--- a/graph/telemetry/istio/appender/extensions_test.go
+++ b/graph/telemetry/istio/appender/extensions_test.go
@@ -13,11 +13,11 @@ import (
 	"k8s.io/client-go/tools/clientcmd/api"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/graph"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/prometheus"
 	"github.com/kiali/kiali/prometheus/prometheustest"
diff --git a/graph/telemetry/istio/appender/health_test.go b/graph/telemetry/istio/appender/health_test.go
index 0f2b07eaf..8fc7bddfa 100644
--- a/graph/telemetry/istio/appender/health_test.go
+++ b/graph/telemetry/istio/appender/health_test.go
@@ -17,11 +17,11 @@ import (
 	ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/graph"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/prometheus/prometheustest"
diff --git a/graph/telemetry/istio/appender/service_entry_test.go b/graph/telemetry/istio/appender/service_entry_test.go
index 5bf647ffc..37b1af62e 100644
--- a/graph/telemetry/istio/appender/service_entry_test.go
+++ b/graph/telemetry/istio/appender/service_entry_test.go
@@ -11,12 +11,12 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/graph"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/istio/istiotest"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/models"
 )
diff --git a/handlers/apps_test.go b/handlers/apps_test.go
index 6ef1647b2..9b835235b 100644
--- a/handlers/apps_test.go
+++ b/handlers/apps_test.go
@@ -22,11 +22,11 @@ import (
 	"k8s.io/client-go/tools/clientcmd/api"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/handlers/authentication"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/prometheus"
diff --git a/handlers/authentication/openid_auth_controller_test.go b/handlers/authentication/openid_auth_controller_test.go
index 3f686b5a2..9a1915014 100644
--- a/handlers/authentication/openid_auth_controller_test.go
+++ b/handlers/authentication/openid_auth_controller_test.go
@@ -20,10 +20,10 @@ import (
 	"github.com/stretchr/testify/require"
 	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/util"
 )
diff --git a/handlers/authentication/token_auth_controller_test.go b/handlers/authentication/token_auth_controller_test.go
index faabc23ff..ced337366 100644
--- a/handlers/authentication/token_auth_controller_test.go
+++ b/handlers/authentication/token_auth_controller_test.go
@@ -14,10 +14,10 @@ import (
 	k8s_errors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/util"
 )
diff --git a/handlers/authentication_test.go b/handlers/authentication_test.go
index 53ee9c40a..9ebf8e198 100644
--- a/handlers/authentication_test.go
+++ b/handlers/authentication_test.go
@@ -18,11 +18,11 @@ import (
 	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/client-go/tools/clientcmd/api"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/handlers/authentication"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/util"
 )
diff --git a/handlers/config_test.go b/handlers/config_test.go
index a7e39168d..b62bc02f4 100644
--- a/handlers/config_test.go
+++ b/handlers/config_test.go
@@ -11,10 +11,10 @@ import (
 	prom_v1 "github.com/prometheus/client_golang/api/prometheus/v1"
 	"github.com/stretchr/testify/require"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/handlers"
 	"github.com/kiali/kiali/istio/istiotest"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/prometheus/prometheustest"
 )
diff --git a/handlers/mesh_test.go b/handlers/mesh_test.go
index aef4f27e7..332af96fc 100644
--- a/handlers/mesh_test.go
+++ b/handlers/mesh_test.go
@@ -14,13 +14,13 @@ import (
 	"k8s.io/client-go/tools/clientcmd/api"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/handlers"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/istio/istiotest"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/prometheus"
diff --git a/handlers/namespaces_test.go b/handlers/namespaces_test.go
index 795f62368..db5da552b 100644
--- a/handlers/namespaces_test.go
+++ b/handlers/namespaces_test.go
@@ -11,11 +11,11 @@ import (
 	"github.com/stretchr/testify/assert"
 	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/handlers"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/prometheus"
 	"github.com/kiali/kiali/prometheus/prometheustest"
diff --git a/handlers/proxy_logging_test.go b/handlers/proxy_logging_test.go
index 5d15baa93..6983602c4 100644
--- a/handlers/proxy_logging_test.go
+++ b/handlers/proxy_logging_test.go
@@ -12,12 +12,12 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/handlers"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/prometheus/prometheustest"
 	"github.com/kiali/kiali/tracing"
diff --git a/handlers/workloads_test.go b/handlers/workloads_test.go
index 2156c45e5..42902dd32 100644
--- a/handlers/workloads_test.go
+++ b/handlers/workloads_test.go
@@ -11,11 +11,11 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/prometheus/prometheustest"
 	"github.com/kiali/kiali/tracing"
diff --git a/istio/discovery_internal_test.go b/istio/discovery_internal_test.go
index c2b485688..b7fd2ded8 100644
--- a/istio/discovery_internal_test.go
+++ b/istio/discovery_internal_test.go
@@ -11,9 +11,9 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/models"
 )
diff --git a/istio/discovery_test.go b/istio/discovery_test.go
index 3ee0dcfdb..2efc44cb0 100644
--- a/istio/discovery_test.go
+++ b/istio/discovery_test.go
@@ -24,10 +24,10 @@ import (
 	"k8s.io/client-go/rest"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/tests/testutils"
diff --git a/istio/version_test.go b/istio/version_test.go
index 316853304..298b1378f 100644
--- a/istio/version_test.go
+++ b/istio/version_test.go
@@ -12,9 +12,9 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 )
 
diff --git a/mesh/api/api_test.go b/mesh/api/api_test.go
index a88d40512..d8960bea8 100644
--- a/mesh/api/api_test.go
+++ b/mesh/api/api_test.go
@@ -23,11 +23,11 @@ import (
 	"k8s.io/client-go/rest"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/grafana"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/kubernetes/kubetest"
 	"github.com/kiali/kiali/mesh"
 	"github.com/kiali/kiali/models"
@@ -163,7 +163,6 @@ V/InYncUvcXt0M4JJSUJi/u6VBKSYYDIHt3mk9Le2qlMQuHkOQ1ZcuEOM2CU/KtO
 	}
 
 	ztunnelObject := &apps_v1.DaemonSet{
-
 		TypeMeta: v1.TypeMeta{
 			APIVersion: kubernetes.DaemonSets.GroupVersion().String(),
 			Kind:       kubernetes.DaemonSets.Kind,
@@ -358,7 +357,7 @@ func TestMeshGraph(t *testing.T) {
 		// The diff is more readable using cmp
 		t.Logf("%s", cmp.Diff(string(expected), string(actual)))
 		// The dump is more useful for updating the .expected file
-		//t.Logf("%s", string(actual))
+		// t.Logf("%s", string(actual))
 	}
 	assert.Equal(t, 200, resp.StatusCode)
 }
diff --git a/server/server_test.go b/server/server_test.go
index 61c391d3d..9c3719069 100644
--- a/server/server_test.go
+++ b/server/server_test.go
@@ -22,10 +22,10 @@ import (
 	"github.com/stretchr/testify/assert"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/config/security"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/util"
 )
 
diff --git a/tests/integration/controller/validations_test.go b/tests/integration/controller/validations_test.go
index bc1a670dc..6081024de 100644
--- a/tests/integration/controller/validations_test.go
+++ b/tests/integration/controller/validations_test.go
@@ -13,11 +13,11 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	"github.com/kiali/kiali/business"
+	"github.com/kiali/kiali/cache"
 	"github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/controller"
 	"github.com/kiali/kiali/istio"
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/kubernetes/cache"
 	"github.com/kiali/kiali/models"
 	"github.com/kiali/kiali/util"
 )
diff --git a/tests/integration/utils/kiali/kiali_client.go b/tests/integration/utils/kiali/kiali_client.go
index 8ff07b8cf..de4679226 100644
--- a/tests/integration/utils/kiali/kiali_client.go
+++ b/tests/integration/utils/kiali/kiali_client.go
@@ -119,7 +119,7 @@ func NewKialiClient() (c *KialiClient) {
 }
 
 func (c *KialiClient) KialiAuthStrategy() (string, error) {
-	body, _, _, err := httpGETWithRetry(c.kialiURL+"/api/auth/info", c.GetAuth(), TIMEOUT, nil, nil)
+	body, _, _, err := httpGETWithRetry(c.kialiURL+"/api/auth/info", c.GetAuth(), TIMEOUT, nil, nil, config.NewConfig())
 	if err == nil {
 		authStrategy := new(AuthStrategy)
 		err = json.Unmarshal(body, &authStrategy)
@@ -134,7 +134,7 @@ func (c *KialiClient) KialiAuthStrategy() (string, error) {
 }
 
 func KialiStatus() (bool, int, error) {
-	_, code, _, err := httpGETWithRetry(client.kialiURL+"/api/istio/status", client.GetAuth(), TIMEOUT, nil, nil)
+	_, code, _, err := httpGETWithRetry(client.kialiURL+"/api/istio/status", client.GetAuth(), TIMEOUT, nil, nil, config.NewConfig())
 	if err == nil {
 		return true, code, nil
 	} else {
@@ -458,7 +458,7 @@ func ObjectMetrics(namespace, service, objectType string, params map[string]stri
 
 func ObjectDashboard(namespace, name, objectType string) (*models.MonitoringDashboard, error) {
 	url := fmt.Sprintf("%s/api/namespaces/%s/%s/%s/dashboard", client.kialiURL, namespace, objectType, name)
-	body, _, _, err := httpGETWithRetry(url, client.GetAuth(), TIMEOUT, nil, nil)
+	body, _, _, err := httpGETWithRetry(url, client.GetAuth(), TIMEOUT, nil, nil, config.NewConfig())
 	if err == nil {
 		response := new(models.MonitoringDashboard)
 		// tests are checking only common response for different object types, ignore the error
@@ -522,7 +522,7 @@ func getRequestAndUnmarshalInto[T any](url string, response *T) (int, error) {
 }
 
 func getRequestAndUnmarshalIntoWithCustomTimeout[T any](url string, timeout time.Duration, response *T) (int, error) {
-	body, code, _, err := httpGETWithRetry(url, client.GetAuth(), timeout, nil, nil)
+	body, code, _, err := httpGETWithRetry(url, client.GetAuth(), timeout, nil, nil, config.NewConfig())
 	if err != nil {
 		return code, err
 	}
@@ -577,7 +577,7 @@ func FirstPodName(name, namespace string) (string, error) {
 
 func PodLogs(name, namespace string, params map[string]string) (*business.PodLog, error) {
 	url := fmt.Sprintf("%s/api/namespaces/%s/pods/%s/logs?sinceTime=%d&%s", client.kialiURL, namespace, name, TimeSinceSeconds(), ParamsAsString(params))
-	body, _, _, err := httpGETWithRetry(url, client.GetAuth(), TIMEOUT, nil, nil)
+	body, _, _, err := httpGETWithRetry(url, client.GetAuth(), TIMEOUT, nil, nil, config.NewConfig())
 	if err == nil {
 		logs := new(business.PodLog)
 		err = json.Unmarshal(body, &logs)
diff --git a/tests/integration/utils/kiali/retry.go b/tests/integration/utils/kiali/retry.go
index c04d8395b..9a4ee3895 100644
--- a/tests/integration/utils/kiali/retry.go
+++ b/tests/integration/utils/kiali/retry.go
@@ -22,12 +22,12 @@ func withRetry(f func() error, retries int) error {
 }
 
 // httpGETWithRetry wraps the httpGET function with retries.
-func httpGETWithRetry(url string, auth *config.Auth, timeout time.Duration, customHeaders map[string]string, cookies []*http.Cookie) ([]byte, int, []*http.Cookie, error) {
+func httpGETWithRetry(url string, auth *config.Auth, timeout time.Duration, customHeaders map[string]string, cookies []*http.Cookie, conf *config.Config) ([]byte, int, []*http.Cookie, error) {
 	var body []byte
 	var code int
 	var err error
 	err = withRetry(func() error {
-		body, code, cookies, err = httputil.HttpGet(url, auth, timeout, customHeaders, cookies)
+		body, code, cookies, err = httputil.HttpGet(url, auth, timeout, customHeaders, cookies, conf)
 		return err
 	}, 3)
 	return body, code, cookies, err
diff --git a/util/filetest/testing.go b/util/filetest/testing.go
new file mode 100644
index 000000000..cb87f7888
--- /dev/null
+++ b/util/filetest/testing.go
@@ -0,0 +1,22 @@
+package filetest
+
+import (
+	"os"
+	"testing"
+)
+
+func TempFile(t *testing.T, contents []byte) *os.File {
+	t.Helper()
+
+	f, err := os.CreateTemp(t.TempDir(), "")
+	if err != nil {
+		t.Fatalf("Unable to create temp file: %s", err)
+	}
+
+	if _, err := f.Write(contents); err != nil {
+		t.Fatalf("Unable to write contents to temp file %s: %s", f.Name(), err)
+	}
+
+	t.Cleanup(func() { f.Close() })
+	return f
+}
diff --git a/util/httputil/http_util_test.go b/util/httputil/http_util_test.go
index 3d526bce2..401ea7e4f 100644
--- a/util/httputil/http_util_test.go
+++ b/util/httputil/http_util_test.go
@@ -143,6 +143,6 @@ func TestHTTPPostSendsPostRequest(t *testing.T) {
 	}))
 	t.Cleanup(server.Close)
 
-	_, _, _, err := httputil.HttpPost(server.URL, nil, nil, time.Second, nil)
+	_, _, _, err := httputil.HttpPost(server.URL, nil, nil, time.Second, nil, config.NewConfig())
 	assert.NoError(err)
 }