From dbac6c523b729c662164b3092ecc7c041d1f20b9 Mon Sep 17 00:00:00 2001
From: Jorge Turrado <jorge_turrado@hotmail.es>
Date: Thu, 2 Feb 2023 00:08:00 +0100
Subject: [PATCH 1/8] update changelog

Signed-off-by: Jorge Turrado <jorge_turrado@hotmail.es>
---
 CHANGELOG.md                                  |   1 +
 Makefile                                      |  12 +-
 config/e2e/create_cas_volume.yml              |  15 +
 config/e2e/kustomization.yaml                 |  10 +
 pkg/util/certificates.go                      |  60 ++++
 pkg/util/http.go                              |  18 ++
 tests/helper/helper.go                        | 142 +++++++++
 .../global_custom_ca/global_custom_ca_test.go | 284 ++++++++++++++++++
 tests/utils/setup_test.go                     |  18 ++
 9 files changed, 554 insertions(+), 6 deletions(-)
 create mode 100644 config/e2e/create_cas_volume.yml
 create mode 100644 config/e2e/kustomization.yaml
 create mode 100644 pkg/util/certificates.go
 create mode 100644 tests/internals/global_custom_ca/global_custom_ca_test.go

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 13ca27ad27b..9d8192df584 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -49,6 +49,7 @@ To learn more about active deprecations, we recommend checking [GitHub Discussio
 
 Here is an overview of all **stable** additions:
 
+- **General**: Add support to register custom CAs globally in KEDA operator ([#4168](https://github.com/kedacore/keda/issues/4168))
 - **General**: Introduce admission webhooks to automatically validate resource changes to prevent misconfiguration and enforce best practices ([#3755](https://github.com/kedacore/keda/issues/3755))
 - **General**: Introduce new ArangoDB Scaler ([#4000](https://github.com/kedacore/keda/issues/4000))
 - **Prometheus Metrics**: Introduce scaler activity in Prometheus metrics ([#4114](https://github.com/kedacore/keda/issues/4114))
diff --git a/Makefile b/Makefile
index bc48f92a581..ee0d43580f1 100644
--- a/Makefile
+++ b/Makefile
@@ -236,13 +236,13 @@ set-version:
 
 ##@ Deployment
 
-install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
+install: kustomize manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
 	$(KUSTOMIZE) build config/crd | kubectl apply -f -
 
-uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config.
+uninstall: kustomize manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config.
 	$(KUSTOMIZE) build config/crd | kubectl delete -f -
 
-deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
+deploy: kustomize manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
 	cd config/manager && \
 	$(KUSTOMIZE) edit set image ghcr.io/kedacore/keda=${IMAGE_CONTROLLER} && \
 	if [ "$(AZURE_RUN_AAD_POD_IDENTITY_TESTS)" = true ]; then \
@@ -274,10 +274,10 @@ deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in
 	# until this issue is solved: https://github.com/kubernetes-sigs/kustomize/issues/1009
 	@sed -i".out" -e 's@version:[ ].*@version: $(VERSION)@g' config/default/kustomize-config/metadataLabelTransformer.yaml
 	rm -rf config/default/kustomize-config/metadataLabelTransformer.yaml.out
-	$(KUSTOMIZE) build config/default | kubectl apply -f -
+	$(KUSTOMIZE) build config/e2e | kubectl apply -f -
 
-undeploy: e2e-test-clean-crds ## Undeploy controller from the K8s cluster specified in ~/.kube/config.
-	$(KUSTOMIZE) build config/default | kubectl delete -f -
+undeploy: kustomize e2e-test-clean-crds ## Undeploy controller from the K8s cluster specified in ~/.kube/config.
+	$(KUSTOMIZE) build config/e2e | kubectl delete -f -
 
 ## Location to install dependencies to
 LOCALBIN ?= $(shell pwd)/bin
diff --git a/config/e2e/create_cas_volume.yml b/config/e2e/create_cas_volume.yml
new file mode 100644
index 00000000000..a28cbbd440c
--- /dev/null
+++ b/config/e2e/create_cas_volume.yml
@@ -0,0 +1,15 @@
+- op: add
+  path: /spec/template/spec/containers/0/volumeMounts/1
+  value:
+    name: custom-cas
+    mountPath: /custom-cas
+    readOnly: true
+
+- op: add
+  path: /spec/template/spec/volumes/1
+  value:
+    name: custom-cas
+    secret:
+      defaultMode: 420
+      secretName: custom-cas
+      optional: true
diff --git a/config/e2e/kustomization.yaml b/config/e2e/kustomization.yaml
new file mode 100644
index 00000000000..48cb86a4f30
--- /dev/null
+++ b/config/e2e/kustomization.yaml
@@ -0,0 +1,10 @@
+patchesJson6902:
+- target:
+    group: apps
+    version: v1
+    kind: Deployment
+    name: keda-operator
+  path: create_cas_volume.yml
+
+bases:
+- ../default
diff --git a/pkg/util/certificates.go b/pkg/util/certificates.go
new file mode 100644
index 00000000000..ebfe12ce6a8
--- /dev/null
+++ b/pkg/util/certificates.go
@@ -0,0 +1,60 @@
+/*
+Copyright 2023 The KEDA Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package util
+
+import (
+	"crypto/x509"
+	"fmt"
+	"os"
+	"path"
+
+	logf "sigs.k8s.io/controller-runtime/pkg/log"
+)
+
+const customCAPath = "/custom-cas"
+
+var logger = logf.Log.WithName("certificates")
+
+func getRootCAs() *x509.CertPool {
+	certPool, _ := x509.SystemCertPool()
+	if certPool == nil {
+		certPool = x509.NewCertPool()
+	}
+
+	files, err := os.ReadDir(customCAPath)
+	if err != nil {
+		logger.Error(err, fmt.Sprintf("unable to read %s", customCAPath))
+	}
+
+	for _, file := range files {
+		if file.IsDir() {
+			continue
+		}
+
+		certs, err := os.ReadFile(path.Join(customCAPath, file.Name()))
+		if err != nil {
+			logger.Error(err, fmt.Sprintf("Failed to append %q to certPool", file.Name()))
+		}
+
+		if ok := certPool.AppendCertsFromPEM(certs); !ok {
+			logger.Error(fmt.Errorf("no certs appended"), fmt.Sprintf("the certificate %s hasn't been added to the pool", file.Name()))
+		}
+		logger.V(1).Info(fmt.Sprintf("the certificate %s has been added to the pool", file.Name()))
+	}
+
+	return certPool
+}
diff --git a/pkg/util/http.go b/pkg/util/http.go
index 6655bec437a..923e4e4779e 100644
--- a/pkg/util/http.go
+++ b/pkg/util/http.go
@@ -18,6 +18,7 @@ package util
 
 import (
 	"crypto/tls"
+	"crypto/x509"
 	"fmt"
 	"net/http"
 	"os"
@@ -64,6 +65,22 @@ func initMinTLSVersion(logger logr.Logger) uint16 {
 	return uint16(minVersion)
 }
 
+var rootCAs *x509.CertPool
+
+func init() {
+	setupLog := ctrl.Log.WithName("http_setup")
+	disableKeepAlives = getKeepAliveValue()
+	rootCAs = getRootCAs()
+	minTLSVersion = initMinTLSVersion(setupLog)
+}
+
+func getKeepAliveValue() bool {
+	if val, err := ResolveOsEnvBool("KEDA_HTTP_DISABLE_KEEP_ALIVE", false); err == nil {
+		return val
+	}
+	return false
+}
+
 // HTTPDoer is an interface that matches the Do method on
 // (net/http).Client. It should be used in function signatures
 // instead of raw *http.Clients wherever possible
@@ -83,6 +100,7 @@ func CreateHTTPClient(timeout time.Duration, unsafeSsl bool) *http.Client {
 		TLSClientConfig: &tls.Config{
 			InsecureSkipVerify: unsafeSsl,
 			MinVersion:         GetMinTLSVersion(),
+			RootCAs:            rootCAs,
 		},
 		Proxy: http.ProxyFromEnvironment,
 	}
diff --git a/tests/helper/helper.go b/tests/helper/helper.go
index 0b23f647923..35774d2df5b 100644
--- a/tests/helper/helper.go
+++ b/tests/helper/helper.go
@@ -6,9 +6,16 @@ package helper
 import (
 	"bytes"
 	"context"
+	cryptoRand "crypto/rand"
+	"crypto/rsa"
+	"crypto/x509"
+	"crypto/x509/pkix"
+	"encoding/pem"
 	"fmt"
 	"io"
+	"math/big"
 	"math/rand"
+	"net"
 	"os"
 	"os/exec"
 	"regexp"
@@ -19,6 +26,7 @@ import (
 
 	"github.com/joho/godotenv"
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 	autoscalingv2 "k8s.io/api/autoscaling/v2"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/errors"
@@ -49,6 +57,11 @@ const (
 	StringTrue  = "true"
 )
 
+const (
+	caCrtPath = "/tmp/keda-e2e-ca.crt"
+	caKeyPath = "/tmp/keda-e2e-ca.key"
+)
+
 var _ = godotenv.Load()
 
 var random = rand.New(rand.NewSource(time.Now().UnixNano()))
@@ -619,3 +632,132 @@ func WaitForPodsTerminated(t *testing.T, kc *kubernetes.Clientset, selector, nam
 
 	return false
 }
+
+func GetTestCA(t *testing.T) ([]byte, []byte) {
+	generateCA(t)
+	caCrt, err := os.ReadFile(caCrtPath)
+	require.NoErrorf(t, err, "error reading custom CA crt - %s", err)
+	caKey, err := os.ReadFile(caKeyPath)
+	require.NoErrorf(t, err, "error reading custom CA key - %s", err)
+	return caCrt, caKey
+}
+
+func GenerateServerCert(t *testing.T, domain string) (string, string) {
+	cert := &x509.Certificate{
+		SerialNumber: big.NewInt(2019),
+		Subject: pkix.Name{
+			Organization:  []string{"Company, INC."},
+			Country:       []string{"US"},
+			Province:      []string{""},
+			Locality:      []string{"San Francisco"},
+			StreetAddress: []string{"Golden Gate Bridge"},
+			PostalCode:    []string{"94016"},
+		},
+		DNSNames: []string{
+			domain,
+		},
+		IPAddresses:  []net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback},
+		NotBefore:    time.Now(),
+		NotAfter:     time.Now().AddDate(10, 0, 0),
+		SubjectKeyId: []byte{1, 2, 3, 4, 6},
+		ExtKeyUsage:  []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
+		KeyUsage:     x509.KeyUsageDigitalSignature,
+	}
+
+	certPrivKey, err := rsa.GenerateKey(cryptoRand.Reader, 4096)
+	require.NoErrorf(t, err, "error generating tls key - %s", err)
+
+	caCrtBytes, caKeyBytes := GetTestCA(t)
+	block, _ := pem.Decode(caCrtBytes)
+	if block == nil {
+		t.Fail()
+		return "", ""
+	}
+	ca, err := x509.ParseCertificate(block.Bytes)
+	if err != nil {
+		t.Fail()
+		return "", ""
+	}
+	blockKey, _ := pem.Decode(caKeyBytes)
+	if blockKey == nil {
+		t.Fail()
+		return "", ""
+	}
+	caKey, err := x509.ParsePKCS1PrivateKey(blockKey.Bytes)
+	require.NoErrorf(t, err, "error reading custom CA key - %s", err)
+	certBytes, err := x509.CreateCertificate(cryptoRand.Reader, cert, ca, &certPrivKey.PublicKey, caKey)
+	require.NoErrorf(t, err, "error creating tls cert - %s", err)
+
+	certPEM := new(bytes.Buffer)
+	err = pem.Encode(certPEM, &pem.Block{
+		Type:  "CERTIFICATE",
+		Bytes: certBytes,
+	})
+	require.NoErrorf(t, err, "error encoding cert - %s", err)
+
+	certPrivKeyPEM := new(bytes.Buffer)
+	err = pem.Encode(certPrivKeyPEM, &pem.Block{
+		Type:  "RSA PRIVATE KEY",
+		Bytes: x509.MarshalPKCS1PrivateKey(certPrivKey),
+	})
+	require.NoErrorf(t, err, "error encoding key - %s", err)
+
+	return certPEM.String(), certPrivKeyPEM.String()
+}
+
+func generateCA(t *testing.T) {
+	_, err := os.Stat(caCrtPath)
+	if err == nil {
+		return
+	}
+	ca := &x509.Certificate{
+		SerialNumber: big.NewInt(2019),
+		Subject: pkix.Name{
+			Organization:  []string{"Company, INC."},
+			Country:       []string{"US"},
+			Province:      []string{""},
+			Locality:      []string{"San Francisco"},
+			StreetAddress: []string{"Golden Gate Bridge"},
+			PostalCode:    []string{"94016"},
+		},
+		NotBefore:             time.Now(),
+		NotAfter:              time.Now().AddDate(10, 0, 0),
+		IsCA:                  true,
+		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
+		KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
+		BasicConstraintsValid: true,
+	}
+
+	// create our private and public key
+	caPrivKey, err := rsa.GenerateKey(cryptoRand.Reader, 4096)
+	require.NoErrorf(t, err, "error generating custom CA key - %s", err)
+
+	// create the CA
+	caBytes, err := x509.CreateCertificate(cryptoRand.Reader, ca, ca, &caPrivKey.PublicKey, caPrivKey)
+	require.NoErrorf(t, err, "error generating custom CA - %s", err)
+
+	// pem encode
+	crtFile, err := os.OpenFile(caCrtPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
+	require.NoErrorf(t, err, "error opening custom CA file - %s", err)
+	err = pem.Encode(crtFile, &pem.Block{
+		Type:  "CERTIFICATE",
+		Bytes: caBytes,
+	})
+	require.NoErrorf(t, err, "error encoding ca - %s", err)
+	if err := crtFile.Close(); err != nil {
+		require.NoErrorf(t, err, "error closing custom CA file - %s", err)
+	}
+
+	keyFile, err := os.OpenFile(caKeyPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
+	if err != nil {
+		require.NoErrorf(t, err, "error opening custom CA key file- %s", err)
+	}
+	err = pem.Encode(keyFile, &pem.Block{
+		Type:  "RSA PRIVATE KEY",
+		Bytes: x509.MarshalPKCS1PrivateKey(caPrivKey),
+	})
+	require.NoErrorf(t, err, "error encoding CA key - %s", err)
+	if err := keyFile.Close(); err != nil {
+		require.NoErrorf(t, err, "error closing custom CA key file- %s", err)
+	}
+}
diff --git a/tests/internals/global_custom_ca/global_custom_ca_test.go b/tests/internals/global_custom_ca/global_custom_ca_test.go
new file mode 100644
index 00000000000..a48c6f1d7b3
--- /dev/null
+++ b/tests/internals/global_custom_ca/global_custom_ca_test.go
@@ -0,0 +1,284 @@
+//go:build e2e
+// +build e2e
+
+package global_custom_ca_test
+
+import (
+	"encoding/base64"
+	"fmt"
+	"testing"
+
+	"github.com/joho/godotenv"
+	"github.com/stretchr/testify/assert"
+	"k8s.io/client-go/kubernetes"
+
+	. "github.com/kedacore/keda/v2/tests/helper"
+)
+
+// Load environment variables from .env file
+var _ = godotenv.Load("../../.env")
+
+const (
+	testName = "global-custom-ca-test"
+)
+
+var (
+	testNamespace               = fmt.Sprintf("%s-ns", testName)
+	deploymentName              = fmt.Sprintf("%s-deployment", testName)
+	metricsServerDeploymentName = fmt.Sprintf("%s-metrics-server", testName)
+	servciceName                = fmt.Sprintf("%s-service", testName)
+	triggerAuthName             = fmt.Sprintf("%s-ta", testName)
+	scaledObjectName            = fmt.Sprintf("%s-so", testName)
+	secretName                  = fmt.Sprintf("%s-secret", testName)
+	metricsServerEndpoint       = fmt.Sprintf("http://%s.%s.svc.cluster.local:8080/api/value", servciceName, testNamespace)
+	metricsServerHTTPSEndpoint  = fmt.Sprintf("https://%s.%s.svc.cluster.local:4333/api/value", servciceName, testNamespace)
+	minReplicaCount             = 0
+	maxReplicaCount             = 2
+)
+
+type templateData struct {
+	TestNamespace               string
+	DeploymentName              string
+	MetricsServerDeploymentName string
+	MetricsServerEndpoint       string
+	MetricsServerHTTPSEndpoint  string
+	ServciceName                string
+	ScaledObjectName            string
+	TriggerAuthName             string
+	TLSCertificate              string
+	TLSKey                      string
+	SecretName                  string
+	MetricValue                 int
+	MinReplicaCount             string
+	MaxReplicaCount             string
+}
+
+const (
+	secretTemplate = `apiVersion: v1
+kind: Secret
+metadata:
+  name: {{.SecretName}}
+  namespace: {{.TestNamespace}}
+data:
+  AUTH_PASSWORD: U0VDUkVUCg==
+  AUTH_USERNAME: VVNFUgo=
+`
+
+	tlsSecretTemplate = `apiVersion: v1
+kind: Secret
+metadata:
+  name: {{.SecretName}}-tls
+  namespace: {{.TestNamespace}}
+data:
+  tls.crt: {{.TLSCertificate}}
+  tls.key: {{.TLSKey}}
+`
+
+	triggerAuthenticationTemplate = `apiVersion: keda.sh/v1alpha1
+kind: TriggerAuthentication
+metadata:
+  name: {{.TriggerAuthName}}
+  namespace: {{.TestNamespace}}
+spec:
+  secretTargetRef:
+    - parameter: username
+      name: {{.SecretName}}
+      key: AUTH_USERNAME
+    - parameter: password
+      name: {{.SecretName}}
+      key: AUTH_PASSWORD
+`
+
+	metricsServerdeploymentTemplate = `
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{.MetricsServerDeploymentName}}
+  namespace: {{.TestNamespace}}
+  labels:
+    app: {{.MetricsServerDeploymentName}}
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: {{.MetricsServerDeploymentName}}
+  template:
+    metadata:
+      labels:
+        app: {{.MetricsServerDeploymentName}}
+    spec:
+      volumes:
+      - name: certificates
+        secret:
+          defaultMode: 420
+          secretName: {{.SecretName}}-tls
+      containers:
+      - name: metrics
+        image: ghcr.io/kedacore/tests-metrics-api
+        ports:
+        - containerPort: 8080
+          name: http
+        - containerPort: 4333
+          name: https
+        envFrom:
+        - secretRef:
+            name: {{.SecretName}}
+        env:
+        - name: USE_TLS
+          value: "true"
+        volumeMounts:
+        - mountPath: /certs
+          name: certificates
+          readOnly: true
+        imagePullPolicy: Always
+`
+
+	serviceTemplate = `
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{.ServciceName}}
+  namespace: {{.TestNamespace}}
+spec:
+  selector:
+    app: {{.MetricsServerDeploymentName}}
+  ports:
+  - port: 8080
+    targetPort: 8080
+    name: http
+  - port: 4333
+    targetPort: 4333
+    name: https
+`
+
+	deploymentTemplate = `
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  labels:
+    app: {{.DeploymentName}}
+  name: {{.DeploymentName}}
+  namespace: {{.TestNamespace}}
+spec:
+  selector:
+    matchLabels:
+      app: {{.DeploymentName}}
+  replicas: 0
+  template:
+    metadata:
+      labels:
+        app: {{.DeploymentName}}
+    spec:
+      containers:
+      - name: nginx
+        image: nginx:1.14.2
+        ports:
+        - containerPort: 80
+`
+
+	scaledObjectTemplate = `
+apiVersion: keda.sh/v1alpha1
+kind: ScaledObject
+metadata:
+  name: {{.ScaledObjectName}}
+  namespace: {{.TestNamespace}}
+  labels:
+    app: {{.DeploymentName}}
+spec:
+  scaleTargetRef:
+    name: {{.DeploymentName}}
+  minReplicaCount: {{.MinReplicaCount}}
+  maxReplicaCount: {{.MaxReplicaCount}}
+  cooldownPeriod:  1
+  triggers:
+  - type: metrics-api
+    metadata:
+      targetValue: "5"
+      url: "{{.MetricsServerHTTPSEndpoint}}"
+      valueLocation: 'value'
+      authMode: "basic"
+      method: "query"
+    authenticationRef:
+      name: {{.TriggerAuthName}}
+`
+	updateMetricTemplate = `apiVersion: batch/v1
+kind: Job
+metadata:
+  name: update-metric-value
+  namespace: {{.TestNamespace}}
+spec:
+  ttlSecondsAfterFinished: 0
+  template:
+    spec:
+      containers:
+      - name: curl-client
+        image: curlimages/curl
+        imagePullPolicy: Always
+        command: ["curl", "-X", "POST", "{{.MetricsServerEndpoint}}/{{.MetricValue}}"]
+      restartPolicy: Never`
+)
+
+func TestCustomCa(t *testing.T) {
+	// setup
+	t.Log("--- setting up ---")
+	// Create kubernetes resources
+	kc := GetKubernetesClient(t)
+	data, templates := getTemplateData(t)
+	CreateKubernetesResources(t, kc, testNamespace, data, templates)
+
+	assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 180, 3),
+		"replica count should be %d after 3 minutes", minReplicaCount)
+
+	// test scaling
+	testScaleOut(t, kc, data)
+	testScaleIn(t, kc, data)
+
+	// cleanup
+	DeleteKubernetesResources(t, kc, testNamespace, data, templates)
+}
+
+func testScaleOut(t *testing.T, kc *kubernetes.Clientset, data templateData) {
+	t.Log("--- testing scale out ---")
+	data.MetricValue = 50
+	KubectlApplyWithTemplate(t, data, "updateMetricTemplate", updateMetricTemplate)
+
+	assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, maxReplicaCount, 60, 3),
+		"replica count should be %d after 3 minutes", maxReplicaCount)
+}
+
+func testScaleIn(t *testing.T, kc *kubernetes.Clientset, data templateData) {
+	t.Log("--- testing scale in ---")
+	data.MetricValue = 0
+	KubectlApplyWithTemplate(t, data, "updateMetricTemplate", updateMetricTemplate)
+
+	assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, 3),
+		"replica count should be %d after 3 minutes", minReplicaCount)
+}
+
+func getTemplateData(t *testing.T) (templateData, []Template) {
+	tlsCrt, TLSKey := GenerateServerCert(t, fmt.Sprintf("%s.%s.svc.cluster.local", servciceName, testNamespace))
+	return templateData{
+			TestNamespace:               testNamespace,
+			DeploymentName:              deploymentName,
+			MetricsServerDeploymentName: metricsServerDeploymentName,
+			ServciceName:                servciceName,
+			TriggerAuthName:             triggerAuthName,
+			ScaledObjectName:            scaledObjectName,
+			SecretName:                  secretName,
+			MetricsServerEndpoint:       metricsServerEndpoint,
+			MetricsServerHTTPSEndpoint:  metricsServerHTTPSEndpoint,
+			MinReplicaCount:             fmt.Sprintf("%v", minReplicaCount),
+			MaxReplicaCount:             fmt.Sprintf("%v", maxReplicaCount),
+			TLSCertificate:              base64.StdEncoding.EncodeToString([]byte(tlsCrt)),
+			TLSKey:                      base64.StdEncoding.EncodeToString([]byte(TLSKey)),
+			MetricValue:                 0,
+		}, []Template{
+			{Name: "secretTemplate", Config: secretTemplate},
+			{Name: "metricsServerdeploymentTemplate", Config: metricsServerdeploymentTemplate},
+			{Name: "serviceTemplate", Config: serviceTemplate},
+			{Name: "tlsSecretTemplate", Config: tlsSecretTemplate},
+			{Name: "triggerAuthenticationTemplate", Config: triggerAuthenticationTemplate},
+			{Name: "deploymentTemplate", Config: deploymentTemplate},
+			{Name: "scaledObjectTemplate", Config: scaledObjectTemplate},
+		}
+}
diff --git a/tests/utils/setup_test.go b/tests/utils/setup_test.go
index 718c8ca26ec..1d4da933756 100644
--- a/tests/utils/setup_test.go
+++ b/tests/utils/setup_test.go
@@ -11,6 +11,7 @@ import (
 	"time"
 
 	"github.com/stretchr/testify/require"
+	corev1 "k8s.io/api/core/v1"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	. "github.com/kedacore/keda/v2/tests/helper"
@@ -166,6 +167,23 @@ func TestSetupGcpIdentityComponents(t *testing.T) {
 }
 
 func TestDeployKEDA(t *testing.T) {
+	KubeClient = GetKubernetesClient(t)
+	CreateNamespace(t, KubeClient, KEDANamespace)
+
+	caCtr, _ := GetTestCA(t)
+	secret := &corev1.Secret{
+		ObjectMeta: v1.ObjectMeta{
+			Name:      "custom-cas",
+			Namespace: KEDANamespace,
+		},
+		StringData: map[string]string{
+			"test-ca.crt": string(caCtr),
+		},
+	}
+
+	_, err := KubeClient.CoreV1().Secrets(KEDANamespace).Create(context.Background(), secret, v1.CreateOptions{})
+	require.NoErrorf(t, err, "error deploying custom CA - %s", err)
+
 	out, err := ExecuteCommandWithDir("make deploy", "../..")
 	require.NoErrorf(t, err, "error deploying KEDA - %s", err)
 

From 45d4662a2d782350c2f343c25c77664556b60dbc Mon Sep 17 00:00:00 2001
From: Jorge Turrado <jorge.turrado@scrm.lidl>
Date: Tue, 7 Feb 2023 15:07:19 +0100
Subject: [PATCH 2/8] update TLS configurations to propagate the HTTP client
 transport values and TLS config CAs

Signed-off-by: Jorge Turrado <jorge.turrado@scrm.lidl>
---
 .../authentication/authentication_helpers.go  | 11 +++---
 pkg/scalers/etcd_scaler.go                    |  2 +-
 pkg/scalers/kafka_scaler.go                   |  2 +-
 pkg/scalers/metrics_api_scaler.go             |  4 +--
 pkg/scalers/pulsar_scaler.go                  |  4 +--
 pkg/scalers/rabbitmq_scaler.go                |  2 +-
 pkg/util/certificates.go                      | 10 ++++--
 pkg/util/http.go                              | 34 +++++++++++--------
 pkg/util/tls_config.go                        | 31 ++++++++---------
 9 files changed, 54 insertions(+), 46 deletions(-)

diff --git a/pkg/scalers/authentication/authentication_helpers.go b/pkg/scalers/authentication/authentication_helpers.go
index db5c9d8a49f..a10b6e702df 100644
--- a/pkg/scalers/authentication/authentication_helpers.go
+++ b/pkg/scalers/authentication/authentication_helpers.go
@@ -85,21 +85,20 @@ func GetBearerToken(auth *AuthMeta) string {
 	return fmt.Sprintf("Bearer %s", auth.BearerToken)
 }
 
-func NewTLSConfig(auth *AuthMeta) (*tls.Config, error) {
+func NewTLSConfig(auth *AuthMeta, unsafeSsl bool) (*tls.Config, error) {
 	return kedautil.NewTLSConfig(
 		auth.Cert,
 		auth.Key,
 		auth.CA,
+		unsafeSsl,
 	)
 }
 
 func CreateHTTPRoundTripper(roundTripperType TransportType, auth *AuthMeta, conf ...*HTTPTransport) (rt http.RoundTripper, err error) {
-	tlsConfig := &tls.Config{
-		MinVersion:         kedautil.GetMinTLSVersion(),
-		InsecureSkipVerify: false,
-	}
+	unsafeSsl := false
+	tlsConfig := kedautil.CreateTLSClientConfig(unsafeSsl)
 	if auth != nil && (auth.CA != "" || auth.EnableTLS) {
-		tlsConfig, err = NewTLSConfig(auth)
+		tlsConfig, err = NewTLSConfig(auth, unsafeSsl)
 		if err != nil || tlsConfig == nil {
 			return nil, fmt.Errorf("error creating the TLS config: %w", err)
 		}
diff --git a/pkg/scalers/etcd_scaler.go b/pkg/scalers/etcd_scaler.go
index e72e2cde761..2c4ad59107a 100644
--- a/pkg/scalers/etcd_scaler.go
+++ b/pkg/scalers/etcd_scaler.go
@@ -154,7 +154,7 @@ func getEtcdClients(metadata *etcdMetadata) (*clientv3.Client, error) {
 	var tlsConfig *tls.Config
 	var err error
 	if metadata.enableTLS {
-		tlsConfig, err = kedautil.NewTLSConfigWithPassword(metadata.cert, metadata.key, metadata.keyPassword, metadata.ca)
+		tlsConfig, err = kedautil.NewTLSConfigWithPassword(metadata.cert, metadata.key, metadata.keyPassword, metadata.ca, false)
 		if err != nil {
 			return nil, err
 		}
diff --git a/pkg/scalers/kafka_scaler.go b/pkg/scalers/kafka_scaler.go
index 5e1cea26174..f7001c2cd39 100644
--- a/pkg/scalers/kafka_scaler.go
+++ b/pkg/scalers/kafka_scaler.go
@@ -318,7 +318,7 @@ func getKafkaClients(metadata kafkaMetadata) (sarama.Client, sarama.ClusterAdmin
 
 	if metadata.enableTLS {
 		config.Net.TLS.Enable = true
-		tlsConfig, err := kedautil.NewTLSConfigWithPassword(metadata.cert, metadata.key, metadata.keyPassword, metadata.ca)
+		tlsConfig, err := kedautil.NewTLSConfigWithPassword(metadata.cert, metadata.key, metadata.keyPassword, metadata.ca, false)
 		if err != nil {
 			return nil, nil, err
 		}
diff --git a/pkg/scalers/metrics_api_scaler.go b/pkg/scalers/metrics_api_scaler.go
index c819d057b9e..668288e797c 100644
--- a/pkg/scalers/metrics_api_scaler.go
+++ b/pkg/scalers/metrics_api_scaler.go
@@ -79,11 +79,11 @@ func NewMetricsAPIScaler(config *ScalerConfig) (Scaler, error) {
 	httpClient := kedautil.CreateHTTPClient(config.GlobalHTTPTimeout, meta.unsafeSsl)
 
 	if meta.enableTLS || len(meta.ca) > 0 {
-		config, err := kedautil.NewTLSConfig(meta.cert, meta.key, meta.ca)
+		config, err := kedautil.NewTLSConfig(meta.cert, meta.key, meta.ca, meta.unsafeSsl)
 		if err != nil {
 			return nil, err
 		}
-		httpClient.Transport = &http.Transport{TLSClientConfig: config}
+		httpClient.Transport = kedautil.CreateHTTPTransportWithTLSConfig(config)
 	}
 
 	return &metricsAPIScaler{
diff --git a/pkg/scalers/pulsar_scaler.go b/pkg/scalers/pulsar_scaler.go
index 63b36b88869..13af199763c 100644
--- a/pkg/scalers/pulsar_scaler.go
+++ b/pkg/scalers/pulsar_scaler.go
@@ -104,11 +104,11 @@ func NewPulsarScaler(config *ScalerConfig) (Scaler, error) {
 
 	if pulsarMetadata.pulsarAuth != nil {
 		if pulsarMetadata.pulsarAuth.CA != "" || pulsarMetadata.pulsarAuth.EnableTLS {
-			config, err := authentication.NewTLSConfig(pulsarMetadata.pulsarAuth)
+			config, err := authentication.NewTLSConfig(pulsarMetadata.pulsarAuth, false)
 			if err != nil {
 				return nil, err
 			}
-			client.Transport = &http.Transport{TLSClientConfig: config}
+			client.Transport = kedautil.CreateHTTPTransportWithTLSConfig(config)
 		}
 
 		if pulsarMetadata.pulsarAuth.EnableBearerAuth || pulsarMetadata.pulsarAuth.EnableBasicAuth {
diff --git a/pkg/scalers/rabbitmq_scaler.go b/pkg/scalers/rabbitmq_scaler.go
index 2f4b059f26e..4def62952a7 100644
--- a/pkg/scalers/rabbitmq_scaler.go
+++ b/pkg/scalers/rabbitmq_scaler.go
@@ -394,7 +394,7 @@ func getConnectionAndChannel(host string, meta *rabbitMQMetadata) (*amqp.Connect
 	var conn *amqp.Connection
 	var err error
 	if meta.enableTLS {
-		tlsConfig, configErr := kedautil.NewTLSConfigWithPassword(meta.cert, meta.key, meta.keyPassword, meta.ca)
+		tlsConfig, configErr := kedautil.NewTLSConfigWithPassword(meta.cert, meta.key, meta.keyPassword, meta.ca, false)
 		if configErr == nil {
 			conn, err = amqp.DialTLS(host, tlsConfig)
 		}
diff --git a/pkg/util/certificates.go b/pkg/util/certificates.go
index ebfe12ce6a8..1670f479311 100644
--- a/pkg/util/certificates.go
+++ b/pkg/util/certificates.go
@@ -29,7 +29,9 @@ const customCAPath = "/custom-cas"
 
 var logger = logf.Log.WithName("certificates")
 
-func getRootCAs() *x509.CertPool {
+var rootCAs *x509.CertPool
+
+func init() {
 	certPool, _ := x509.SystemCertPool()
 	if certPool == nil {
 		certPool = x509.NewCertPool()
@@ -56,5 +58,9 @@ func getRootCAs() *x509.CertPool {
 		logger.V(1).Info(fmt.Sprintf("the certificate %s has been added to the pool", file.Name()))
 	}
 
-	return certPool
+	rootCAs = certPool
+}
+
+func getRootCAs() *x509.CertPool {
+	return rootCAs
 }
diff --git a/pkg/util/http.go b/pkg/util/http.go
index 923e4e4779e..9ece06cd07a 100644
--- a/pkg/util/http.go
+++ b/pkg/util/http.go
@@ -18,7 +18,6 @@ package util
 
 import (
 	"crypto/tls"
-	"crypto/x509"
 	"fmt"
 	"net/http"
 	"os"
@@ -65,8 +64,6 @@ func initMinTLSVersion(logger logr.Logger) uint16 {
 	return uint16(minVersion)
 }
 
-var rootCAs *x509.CertPool
-
 func init() {
 	setupLog := ctrl.Log.WithName("http_setup")
 	disableKeepAlives = getKeepAliveValue()
@@ -96,24 +93,33 @@ func CreateHTTPClient(timeout time.Duration, unsafeSsl bool) *http.Client {
 	if timeout <= 0 {
 		timeout = 300 * time.Millisecond
 	}
+	transport := CreateHTTPTransport(unsafeSsl)
+	httpClient := &http.Client{
+		Timeout:   timeout,
+		Transport: transport,
+	}
+	return httpClient
+}
+
+// CreateHTTPTransport returns a new HTTP Transport with Proxy, Keep alives
+// unsafeSsl parameter allows to avoid tls cert validation if it's required
+func CreateHTTPTransport(unsafeSsl bool) *http.Transport {
+	return CreateHTTPTransportWithTLSConfig(CreateTLSClientConfig(unsafeSsl))
+}
+
+// CreateHTTPTransportWithTLSConfig returns a new HTTP Transport with Proxy, Keep alives
+// using given tls.Config
+func CreateHTTPTransportWithTLSConfig(config *tls.Config) *http.Transport {
 	transport := &http.Transport{
-		TLSClientConfig: &tls.Config{
-			InsecureSkipVerify: unsafeSsl,
-			MinVersion:         GetMinTLSVersion(),
-			RootCAs:            rootCAs,
-		},
-		Proxy: http.ProxyFromEnvironment,
+		TLSClientConfig: config,
+		Proxy:           http.ProxyFromEnvironment,
 	}
 	if disableKeepAlives {
 		// disable keep http connection alive
 		transport.DisableKeepAlives = true
 		transport.IdleConnTimeout = 100 * time.Second
 	}
-	httpClient := &http.Client{
-		Timeout:   timeout,
-		Transport: transport,
-	}
-	return httpClient
+	return transport
 }
 
 func GetMinTLSVersion() uint16 {
diff --git a/pkg/util/tls_config.go b/pkg/util/tls_config.go
index 3a64f1ed752..c00db439c19 100644
--- a/pkg/util/tls_config.go
+++ b/pkg/util/tls_config.go
@@ -51,12 +51,8 @@ func decryptClientKey(clientKey, clientKeyPassword string) ([]byte, error) {
 // NewTLSConfigWithPassword returns a *tls.Config using the given ceClient cert, ceClient key,
 // and CA certificate. If clientKeyPassword is not empty the provided password will be used to
 // decrypt the given key. If none are appropriate, a nil *tls.Config is returned.
-func NewTLSConfigWithPassword(clientCert, clientKey, clientKeyPassword, caCert string) (*tls.Config, error) {
-	valid := false
-
-	config := &tls.Config{
-		MinVersion: GetMinTLSVersion(),
-	}
+func NewTLSConfigWithPassword(clientCert, clientKey, clientKeyPassword, caCert string, unsafeSsl bool) (*tls.Config, error) {
+	config := CreateTLSClientConfig(unsafeSsl)
 
 	if clientCert != "" && clientKey != "" {
 		key := []byte(clientKey)
@@ -73,18 +69,10 @@ func NewTLSConfigWithPassword(clientCert, clientKey, clientKeyPassword, caCert s
 			return nil, fmt.Errorf("error parse X509KeyPair: %w", err)
 		}
 		config.Certificates = []tls.Certificate{cert}
-		valid = true
 	}
 
 	if caCert != "" {
-		caCertPool := x509.NewCertPool()
-		caCertPool.AppendCertsFromPEM([]byte(caCert))
-		config.RootCAs = caCertPool
-		valid = true
-	}
-
-	if !valid {
-		config = nil
+		config.RootCAs.AppendCertsFromPEM([]byte(caCert))
 	}
 
 	return config, nil
@@ -92,6 +80,15 @@ func NewTLSConfigWithPassword(clientCert, clientKey, clientKeyPassword, caCert s
 
 // NewTLSConfig returns a *tls.Config using the given ceClient cert, ceClient key,
 // and CA certificate. If none are appropriate, a nil *tls.Config is returned.
-func NewTLSConfig(clientCert, clientKey, caCert string) (*tls.Config, error) {
-	return NewTLSConfigWithPassword(clientCert, clientKey, "", caCert)
+func NewTLSConfig(clientCert, clientKey, caCert string, unsafeSsl bool) (*tls.Config, error) {
+	return NewTLSConfigWithPassword(clientCert, clientKey, "", caCert, unsafeSsl)
+}
+
+// createTLSClientConfig returns a new TLS Config
+// unsafeSsl parameter allows to avoid tls cert validation if it's required
+func CreateTLSClientConfig(unsafeSsl bool) *tls.Config {
+	return &tls.Config{
+		InsecureSkipVerify: unsafeSsl,
+		RootCAs:            getRootCAs(),
+	}
 }

From 2fc583e482d92a954d616a77785fc0976f26fec7 Mon Sep 17 00:00:00 2001
From: Jorge Turrado <jorge.turrado@scrm.lidl>
Date: Tue, 7 Feb 2023 15:09:14 +0100
Subject: [PATCH 3/8] returns a copy of rootCAs to keep global CAs unmodifed

Signed-off-by: Jorge Turrado <jorge.turrado@scrm.lidl>
---
 pkg/util/certificates.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pkg/util/certificates.go b/pkg/util/certificates.go
index 1670f479311..356bb3ec1d3 100644
--- a/pkg/util/certificates.go
+++ b/pkg/util/certificates.go
@@ -62,5 +62,5 @@ func init() {
 }
 
 func getRootCAs() *x509.CertPool {
-	return rootCAs
+	return rootCAs.Clone()
 }

From 4727f8e5a8cd59dd49481ece81f3fc316e2b2dd7 Mon Sep 17 00:00:00 2001
From: Jorge Turrado <jorge_turrado@hotmail.es>
Date: Thu, 9 Feb 2023 21:27:34 +0100
Subject: [PATCH 4/8] integrate changes

Signed-off-by: Jorge Turrado <jorge_turrado@hotmail.es>
---
 pkg/scalers/arangodb_scaler.go                |  7 +-
 pkg/scalers/elasticsearch_scaler.go           | 11 +--
 pkg/scalers/ibmmq_scaler.go                   | 10 +--
 pkg/scalers/influxdb_scaler.go                |  7 +-
 pkg/scalers/liiklus/LiiklusService.pb.go      | 20 ++---
 pkg/scalers/liiklus/LiiklusService_grpc.pb.go | 12 +--
 pkg/scalers/redis_scaler.go                   | 17 +---
 pkg/util/http.go                              | 36 ---------
 pkg/util/http_test.go                         | 73 -----------------
 pkg/util/tls_config.go                        | 79 ++++++++++++++-----
 pkg/util/tls_config_test.go                   | 72 ++++++++++++++++-
 11 files changed, 155 insertions(+), 189 deletions(-)
 delete mode 100644 pkg/util/http_test.go

diff --git a/pkg/scalers/arangodb_scaler.go b/pkg/scalers/arangodb_scaler.go
index 9154bd73827..29b343f971c 100644
--- a/pkg/scalers/arangodb_scaler.go
+++ b/pkg/scalers/arangodb_scaler.go
@@ -2,7 +2,6 @@ package scalers
 
 import (
 	"context"
-	"crypto/tls"
 	"fmt"
 	"strconv"
 	"strings"
@@ -15,6 +14,7 @@ import (
 	"k8s.io/metrics/pkg/apis/external_metrics"
 
 	"github.com/kedacore/keda/v2/pkg/scalers/authentication"
+	"github.com/kedacore/keda/v2/pkg/util"
 )
 
 type arangoDBScaler struct {
@@ -97,10 +97,7 @@ func getNewArangoDBClient(meta *arangoDBMetadata) (driver.Client, error) {
 
 	conn, err := http.NewConnection(http.ConnectionConfig{
 		Endpoints: strings.Split(meta.endpoints, ","),
-		TLSConfig: &tls.Config{
-			MinVersion:         tls.VersionTLS13,
-			InsecureSkipVerify: meta.unsafeSsl,
-		},
+		TLSConfig: util.CreateTLSClientConfig(meta.unsafeSsl),
 	})
 	if err != nil {
 		return nil, fmt.Errorf("failed to create a new http connection, %w", err)
diff --git a/pkg/scalers/elasticsearch_scaler.go b/pkg/scalers/elasticsearch_scaler.go
index 73c3cc22788..25929ca678c 100644
--- a/pkg/scalers/elasticsearch_scaler.go
+++ b/pkg/scalers/elasticsearch_scaler.go
@@ -3,12 +3,10 @@ package scalers
 import (
 	"bytes"
 	"context"
-	"crypto/tls"
 	"encoding/json"
 	"errors"
 	"fmt"
 	"io"
-	"net/http"
 	"strconv"
 	"strings"
 
@@ -18,6 +16,7 @@ import (
 	v2 "k8s.io/api/autoscaling/v2"
 	"k8s.io/metrics/pkg/apis/external_metrics"
 
+	"github.com/kedacore/keda/v2/pkg/util"
 	kedautil "github.com/kedacore/keda/v2/pkg/util"
 )
 
@@ -243,13 +242,7 @@ func newElasticsearchClient(meta *elasticsearchMetadata, logger logr.Logger) (*e
 		}
 	}
 
-	transport := http.DefaultTransport.(*http.Transport)
-	transport.TLSClientConfig = &tls.Config{
-		MinVersion:         kedautil.GetMinTLSVersion(),
-		InsecureSkipVerify: meta.unsafeSsl,
-	}
-	config.Transport = transport
-
+	config.Transport = util.CreateHTTPTransport(meta.unsafeSsl)
 	esClient, err := elasticsearch.NewClient(config)
 	if err != nil {
 		logger.Error(err, fmt.Sprintf("Found error when creating client: %s", err))
diff --git a/pkg/scalers/ibmmq_scaler.go b/pkg/scalers/ibmmq_scaler.go
index 700a69e2161..15591524d37 100644
--- a/pkg/scalers/ibmmq_scaler.go
+++ b/pkg/scalers/ibmmq_scaler.go
@@ -3,7 +3,6 @@ package scalers
 import (
 	"bytes"
 	"context"
-	"crypto/tls"
 	"encoding/json"
 	"fmt"
 	"io"
@@ -178,14 +177,7 @@ func (s *IBMMQScaler) getQueueDepthViaHTTP(ctx context.Context) (int64, error) {
 	req.Header.Set("Content-Type", "application/json")
 	req.SetBasicAuth(s.metadata.username, s.metadata.password)
 
-	tr := &http.Transport{
-		TLSClientConfig: &tls.Config{
-			MinVersion:         kedautil.GetMinTLSVersion(),
-			InsecureSkipVerify: s.metadata.tlsDisabled,
-		},
-	}
-	client := kedautil.CreateHTTPClient(s.defaultHTTPTimeout, false)
-	client.Transport = tr
+	client := kedautil.CreateHTTPClient(s.defaultHTTPTimeout, s.metadata.tlsDisabled)
 
 	resp, err := client.Do(req)
 	if err != nil {
diff --git a/pkg/scalers/influxdb_scaler.go b/pkg/scalers/influxdb_scaler.go
index 6a3d605c948..781ad016b8a 100644
--- a/pkg/scalers/influxdb_scaler.go
+++ b/pkg/scalers/influxdb_scaler.go
@@ -2,7 +2,6 @@ package scalers
 
 import (
 	"context"
-	"crypto/tls"
 	"fmt"
 	"strconv"
 
@@ -12,6 +11,7 @@ import (
 	v2 "k8s.io/api/autoscaling/v2"
 	"k8s.io/metrics/pkg/apis/external_metrics"
 
+	"github.com/kedacore/keda/v2/pkg/util"
 	kedautil "github.com/kedacore/keda/v2/pkg/util"
 )
 
@@ -52,10 +52,7 @@ func NewInfluxDBScaler(config *ScalerConfig) (Scaler, error) {
 	client := influxdb2.NewClientWithOptions(
 		meta.serverURL,
 		meta.authToken,
-		influxdb2.DefaultOptions().SetTLSConfig(&tls.Config{
-			MinVersion:         kedautil.GetMinTLSVersion(),
-			InsecureSkipVerify: meta.unsafeSsl,
-		}))
+		influxdb2.DefaultOptions().SetTLSConfig(util.CreateTLSClientConfig(meta.unsafeSsl)))
 
 	return &influxDBScaler{
 		client:     client,
diff --git a/pkg/scalers/liiklus/LiiklusService.pb.go b/pkg/scalers/liiklus/LiiklusService.pb.go
index a0027a6fff3..8d34aea93d9 100644
--- a/pkg/scalers/liiklus/LiiklusService.pb.go
+++ b/pkg/scalers/liiklus/LiiklusService.pb.go
@@ -7,10 +7,10 @@
 package liiklus
 
 import (
-	empty "github.com/golang/protobuf/ptypes/empty"
-	timestamp "github.com/golang/protobuf/ptypes/timestamp"
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
+	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
 	reflect "reflect"
 	sync "sync"
 )
@@ -807,11 +807,11 @@ type ReceiveReply_Record struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Offset    uint64               `protobuf:"varint,1,opt,name=offset,proto3" json:"offset,omitempty"`
-	Key       []byte               `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
-	Value     []byte               `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"`
-	Timestamp *timestamp.Timestamp `protobuf:"bytes,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
-	Replay    bool                 `protobuf:"varint,5,opt,name=replay,proto3" json:"replay,omitempty"`
+	Offset    uint64                 `protobuf:"varint,1,opt,name=offset,proto3" json:"offset,omitempty"`
+	Key       []byte                 `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
+	Value     []byte                 `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"`
+	Timestamp *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	Replay    bool                   `protobuf:"varint,5,opt,name=replay,proto3" json:"replay,omitempty"`
 }
 
 func (x *ReceiveReply_Record) Reset() {
@@ -867,7 +867,7 @@ func (x *ReceiveReply_Record) GetValue() []byte {
 	return nil
 }
 
-func (x *ReceiveReply_Record) GetTimestamp() *timestamp.Timestamp {
+func (x *ReceiveReply_Record) GetTimestamp() *timestamppb.Timestamp {
 	if x != nil {
 		return x.Timestamp
 	}
@@ -1073,8 +1073,8 @@ var file_LiiklusService_proto_goTypes = []interface{}{
 	(*ReceiveReply_Record)(nil),           // 13: com.github.bsideup.liiklus.ReceiveReply.Record
 	nil,                                   // 14: com.github.bsideup.liiklus.GetOffsetsReply.OffsetsEntry
 	nil,                                   // 15: com.github.bsideup.liiklus.GetEndOffsetsReply.OffsetsEntry
-	(*timestamp.Timestamp)(nil),           // 16: google.protobuf.Timestamp
-	(*empty.Empty)(nil),                   // 17: google.protobuf.Empty
+	(*timestamppb.Timestamp)(nil),         // 16: google.protobuf.Timestamp
+	(*emptypb.Empty)(nil),                 // 17: google.protobuf.Empty
 }
 var file_LiiklusService_proto_depIdxs = []int32{
 	0,  // 0: com.github.bsideup.liiklus.SubscribeRequest.autoOffsetReset:type_name -> com.github.bsideup.liiklus.SubscribeRequest.AutoOffsetReset
diff --git a/pkg/scalers/liiklus/LiiklusService_grpc.pb.go b/pkg/scalers/liiklus/LiiklusService_grpc.pb.go
index 3ad3383d914..4ff6ae6c44f 100644
--- a/pkg/scalers/liiklus/LiiklusService_grpc.pb.go
+++ b/pkg/scalers/liiklus/LiiklusService_grpc.pb.go
@@ -8,10 +8,10 @@ package liiklus
 
 import (
 	context "context"
-	empty "github.com/golang/protobuf/ptypes/empty"
 	grpc "google.golang.org/grpc"
 	codes "google.golang.org/grpc/codes"
 	status "google.golang.org/grpc/status"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
 )
 
 // This is a compile-time assertion to ensure that this generated file
@@ -26,7 +26,7 @@ type LiiklusServiceClient interface {
 	Publish(ctx context.Context, in *PublishRequest, opts ...grpc.CallOption) (*PublishReply, error)
 	Subscribe(ctx context.Context, in *SubscribeRequest, opts ...grpc.CallOption) (LiiklusService_SubscribeClient, error)
 	Receive(ctx context.Context, in *ReceiveRequest, opts ...grpc.CallOption) (LiiklusService_ReceiveClient, error)
-	Ack(ctx context.Context, in *AckRequest, opts ...grpc.CallOption) (*empty.Empty, error)
+	Ack(ctx context.Context, in *AckRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
 	GetOffsets(ctx context.Context, in *GetOffsetsRequest, opts ...grpc.CallOption) (*GetOffsetsReply, error)
 	GetEndOffsets(ctx context.Context, in *GetEndOffsetsRequest, opts ...grpc.CallOption) (*GetEndOffsetsReply, error)
 }
@@ -112,8 +112,8 @@ func (x *liiklusServiceReceiveClient) Recv() (*ReceiveReply, error) {
 	return m, nil
 }
 
-func (c *liiklusServiceClient) Ack(ctx context.Context, in *AckRequest, opts ...grpc.CallOption) (*empty.Empty, error) {
-	out := new(empty.Empty)
+func (c *liiklusServiceClient) Ack(ctx context.Context, in *AckRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
+	out := new(emptypb.Empty)
 	err := c.cc.Invoke(ctx, "/com.github.bsideup.liiklus.LiiklusService/Ack", in, out, opts...)
 	if err != nil {
 		return nil, err
@@ -146,7 +146,7 @@ type LiiklusServiceServer interface {
 	Publish(context.Context, *PublishRequest) (*PublishReply, error)
 	Subscribe(*SubscribeRequest, LiiklusService_SubscribeServer) error
 	Receive(*ReceiveRequest, LiiklusService_ReceiveServer) error
-	Ack(context.Context, *AckRequest) (*empty.Empty, error)
+	Ack(context.Context, *AckRequest) (*emptypb.Empty, error)
 	GetOffsets(context.Context, *GetOffsetsRequest) (*GetOffsetsReply, error)
 	GetEndOffsets(context.Context, *GetEndOffsetsRequest) (*GetEndOffsetsReply, error)
 	mustEmbedUnimplementedLiiklusServiceServer()
@@ -165,7 +165,7 @@ func (UnimplementedLiiklusServiceServer) Subscribe(*SubscribeRequest, LiiklusSer
 func (UnimplementedLiiklusServiceServer) Receive(*ReceiveRequest, LiiklusService_ReceiveServer) error {
 	return status.Errorf(codes.Unimplemented, "method Receive not implemented")
 }
-func (UnimplementedLiiklusServiceServer) Ack(context.Context, *AckRequest) (*empty.Empty, error) {
+func (UnimplementedLiiklusServiceServer) Ack(context.Context, *AckRequest) (*emptypb.Empty, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method Ack not implemented")
 }
 func (UnimplementedLiiklusServiceServer) GetOffsets(context.Context, *GetOffsetsRequest) (*GetOffsetsReply, error) {
diff --git a/pkg/scalers/redis_scaler.go b/pkg/scalers/redis_scaler.go
index 03327e02416..9e96ee7562c 100644
--- a/pkg/scalers/redis_scaler.go
+++ b/pkg/scalers/redis_scaler.go
@@ -2,7 +2,6 @@ package scalers
 
 import (
 	"context"
-	"crypto/tls"
 	"errors"
 	"fmt"
 	"net"
@@ -14,6 +13,7 @@ import (
 	v2 "k8s.io/api/autoscaling/v2"
 	"k8s.io/metrics/pkg/apis/external_metrics"
 
+	"github.com/kedacore/keda/v2/pkg/util"
 	kedautil "github.com/kedacore/keda/v2/pkg/util"
 )
 
@@ -464,10 +464,7 @@ func getRedisClusterClient(ctx context.Context, info redisConnectionInfo) (*redi
 		Password: info.password,
 	}
 	if info.enableTLS {
-		options.TLSConfig = &tls.Config{
-			MinVersion:         kedautil.GetMinTLSVersion(),
-			InsecureSkipVerify: info.unsafeSsl,
-		}
+		options.TLSConfig = util.CreateTLSClientConfig(info.unsafeSsl)
 	}
 
 	// confirm if connected
@@ -489,10 +486,7 @@ func getRedisSentinelClient(ctx context.Context, info redisConnectionInfo, dbInd
 		MasterName:       info.sentinelMaster,
 	}
 	if info.enableTLS {
-		options.TLSConfig = &tls.Config{
-			MinVersion:         kedautil.GetMinTLSVersion(),
-			InsecureSkipVerify: info.unsafeSsl,
-		}
+		options.TLSConfig = util.CreateTLSClientConfig(info.unsafeSsl)
 	}
 
 	// confirm if connected
@@ -511,10 +505,7 @@ func getRedisClient(ctx context.Context, info redisConnectionInfo, dbIndex int)
 		DB:       dbIndex,
 	}
 	if info.enableTLS {
-		options.TLSConfig = &tls.Config{
-			MinVersion:         kedautil.GetMinTLSVersion(),
-			InsecureSkipVerify: info.unsafeSsl,
-		}
+		options.TLSConfig = util.CreateTLSClientConfig(info.unsafeSsl)
 	}
 
 	// confirm if connected
diff --git a/pkg/util/http.go b/pkg/util/http.go
index 9ece06cd07a..25a0e9d74c1 100644
--- a/pkg/util/http.go
+++ b/pkg/util/http.go
@@ -18,20 +18,13 @@ package util
 
 import (
 	"crypto/tls"
-	"fmt"
 	"net/http"
-	"os"
 	"time"
-
-	"github.com/go-logr/logr"
-	ctrl "sigs.k8s.io/controller-runtime"
 )
 
 var disableKeepAlives bool
-var minTLSVersion uint16
 
 func init() {
-	setupLog := ctrl.Log.WithName("http_setup")
 	var err error
 	// This code will be removed in https://github.com/kedacore/keda/pull/4191
 	// nosemgrep: trailofbits.go.invalid-usage-of-modified-variable.invalid-usage-of-modified-variable
@@ -39,36 +32,11 @@ func init() {
 	if err != nil {
 		disableKeepAlives = false
 	}
-
-	minTLSVersion = initMinTLSVersion(setupLog)
-}
-
-func initMinTLSVersion(logger logr.Logger) uint16 {
-	version, found := os.LookupEnv("KEDA_HTTP_MIN_TLS_VERSION")
-	minVersion := tls.VersionTLS12
-	if found {
-		switch version {
-		case "TLS13":
-			minVersion = tls.VersionTLS13
-		case "TLS12":
-			minVersion = tls.VersionTLS12
-		case "TLS11":
-			minVersion = tls.VersionTLS11
-		case "TLS10":
-			minVersion = tls.VersionTLS10
-		default:
-			logger.Info(fmt.Sprintf("%s is not a valid value, using `TLS12`. Allowed values are: `TLS13`,`TLS12`,`TLS11`,`TLS10`", version))
-			minVersion = tls.VersionTLS12
-		}
-	}
-	return uint16(minVersion)
 }
 
 func init() {
-	setupLog := ctrl.Log.WithName("http_setup")
 	disableKeepAlives = getKeepAliveValue()
 	rootCAs = getRootCAs()
-	minTLSVersion = initMinTLSVersion(setupLog)
 }
 
 func getKeepAliveValue() bool {
@@ -121,7 +89,3 @@ func CreateHTTPTransportWithTLSConfig(config *tls.Config) *http.Transport {
 	}
 	return transport
 }
-
-func GetMinTLSVersion() uint16 {
-	return minTLSVersion
-}
diff --git a/pkg/util/http_test.go b/pkg/util/http_test.go
deleted file mode 100644
index 970a6c76dcf..00000000000
--- a/pkg/util/http_test.go
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-Copyright 2023 The KEDA Authors
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package util
-
-import (
-	"crypto/tls"
-	"os"
-	"testing"
-
-	"github.com/go-logr/logr"
-)
-
-type minTLSVersionTestData struct {
-	envSet          bool
-	envValue        string
-	expectedVersion uint16
-}
-
-var minTLSVersionTestDatas = []minTLSVersionTestData{
-	{
-		envSet:          true,
-		envValue:        "TLS10",
-		expectedVersion: tls.VersionTLS10,
-	},
-	{
-		envSet:          true,
-		envValue:        "TLS11",
-		expectedVersion: tls.VersionTLS11,
-	},
-	{
-		envSet:          true,
-		envValue:        "TLS12",
-		expectedVersion: tls.VersionTLS12,
-	},
-	{
-		envSet:          true,
-		envValue:        "TLS13",
-		expectedVersion: tls.VersionTLS13,
-	},
-	{
-		envSet:          false,
-		expectedVersion: tls.VersionTLS12,
-	},
-}
-
-func TestResolveMinTLSVersion(t *testing.T) {
-	defer os.Unsetenv("KEDA_HTTP_MIN_TLS_VERSION")
-	for _, testData := range minTLSVersionTestDatas {
-		os.Unsetenv("KEDA_HTTP_MIN_TLS_VERSION")
-		if testData.envSet {
-			os.Setenv("KEDA_HTTP_MIN_TLS_VERSION", testData.envValue)
-		}
-		minVersion := initMinTLSVersion(logr.Discard())
-
-		if testData.expectedVersion != minVersion {
-			t.Error("Failed to resolve minTLSVersion correctly", "wants", testData.expectedVersion, "got", minVersion)
-		}
-	}
-}
diff --git a/pkg/util/tls_config.go b/pkg/util/tls_config.go
index c00db439c19..078b602a579 100644
--- a/pkg/util/tls_config.go
+++ b/pkg/util/tls_config.go
@@ -21,31 +21,18 @@ import (
 	"crypto/x509"
 	"encoding/pem"
 	"fmt"
+	"os"
 
+	"github.com/go-logr/logr"
 	"github.com/youmark/pkcs8"
+	ctrl "sigs.k8s.io/controller-runtime"
 )
 
-func decryptClientKey(clientKey, clientKeyPassword string) ([]byte, error) {
-	block, _ := pem.Decode([]byte(clientKey))
-
-	key, err := pkcs8.ParsePKCS8PrivateKey(block.Bytes, []byte(clientKeyPassword))
-	if err != nil {
-		return nil, err
-	}
+var minTLSVersion uint16
 
-	pemData, err := x509.MarshalPKCS8PrivateKey(key)
-	if err != nil {
-		return nil, err
-	}
-
-	var pemPrivateBlock = &pem.Block{
-		Type:  "RSA PRIVATE KEY",
-		Bytes: pemData,
-	}
-
-	encodedData := pem.EncodeToMemory(pemPrivateBlock)
-
-	return encodedData, nil
+func init() {
+	setupLog := ctrl.Log.WithName("tls_setup")
+	minTLSVersion = initMinTLSVersion(setupLog)
 }
 
 // NewTLSConfigWithPassword returns a *tls.Config using the given ceClient cert, ceClient key,
@@ -84,11 +71,61 @@ func NewTLSConfig(clientCert, clientKey, caCert string, unsafeSsl bool) (*tls.Co
 	return NewTLSConfigWithPassword(clientCert, clientKey, "", caCert, unsafeSsl)
 }
 
-// createTLSClientConfig returns a new TLS Config
+// CreateTLSClientConfig returns a new TLS Config
 // unsafeSsl parameter allows to avoid tls cert validation if it's required
 func CreateTLSClientConfig(unsafeSsl bool) *tls.Config {
 	return &tls.Config{
 		InsecureSkipVerify: unsafeSsl,
 		RootCAs:            getRootCAs(),
+		MinVersion:         GetMinTLSVersion(),
 	}
 }
+
+// GetMinTLSVersion return the minTLSVersion based on configurations
+func GetMinTLSVersion() uint16 {
+	return minTLSVersion
+}
+
+func initMinTLSVersion(logger logr.Logger) uint16 {
+	version, found := os.LookupEnv("KEDA_HTTP_MIN_TLS_VERSION")
+	minVersion := tls.VersionTLS12
+	if found {
+		switch version {
+		case "TLS13":
+			minVersion = tls.VersionTLS13
+		case "TLS12":
+			minVersion = tls.VersionTLS12
+		case "TLS11":
+			minVersion = tls.VersionTLS11
+		case "TLS10":
+			minVersion = tls.VersionTLS10
+		default:
+			logger.Info(fmt.Sprintf("%s is not a valid value, using `TLS12`. Allowed values are: `TLS13`,`TLS12`,`TLS11`,`TLS10`", version))
+			minVersion = tls.VersionTLS12
+		}
+	}
+	return uint16(minVersion)
+}
+
+func decryptClientKey(clientKey, clientKeyPassword string) ([]byte, error) {
+	block, _ := pem.Decode([]byte(clientKey))
+
+	key, err := pkcs8.ParsePKCS8PrivateKey(block.Bytes, []byte(clientKeyPassword))
+	if err != nil {
+		return nil, err
+	}
+
+	pemData, err := x509.MarshalPKCS8PrivateKey(key)
+	if err != nil {
+		return nil, err
+	}
+
+	var pemPrivateBlock = &pem.Block{
+		Type:  "RSA PRIVATE KEY",
+		Bytes: pemData,
+	}
+
+	encodedData := pem.EncodeToMemory(pemPrivateBlock)
+
+	return encodedData, nil
+}
diff --git a/pkg/util/tls_config_test.go b/pkg/util/tls_config_test.go
index b75bf776b8b..8d9ea2edd1e 100644
--- a/pkg/util/tls_config_test.go
+++ b/pkg/util/tls_config_test.go
@@ -1,9 +1,29 @@
+/*
+Copyright 2023 The KEDA Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
 package util
 
 import (
+	"crypto/tls"
 	"crypto/x509"
+	"os"
 	"strings"
 	"testing"
+
+	"github.com/go-logr/logr"
 )
 
 var randomCACert = `-----BEGIN CERTIFICATE-----
@@ -136,7 +156,7 @@ func TestNewTLSConfig_WithoutPassword(t *testing.T) {
 	}
 	for _, test := range testCases {
 		t.Run(test.name, func(t *testing.T) {
-			config, err := NewTLSConfig(test.cert, test.key, test.CACert)
+			config, err := NewTLSConfig(test.cert, test.key, test.CACert, false)
 			if err != nil {
 				t.Errorf("Should have no error %s", err)
 			}
@@ -203,7 +223,7 @@ func TestNewTLSConfig_WithPassword(t *testing.T) {
 	}
 	for _, test := range testCases {
 		t.Run(test.name, func(t *testing.T) {
-			config, err := NewTLSConfigWithPassword(test.cert, test.key, test.password, test.CACert)
+			config, err := NewTLSConfigWithPassword(test.cert, test.key, test.password, test.CACert, false)
 			if err != nil {
 				t.Errorf("Should have no error: %s", err)
 			}
@@ -225,3 +245,51 @@ func TestNewTLSConfig_WithPassword(t *testing.T) {
 		})
 	}
 }
+
+type minTLSVersionTestData struct {
+	envSet          bool
+	envValue        string
+	expectedVersion uint16
+}
+
+var minTLSVersionTestDatas = []minTLSVersionTestData{
+	{
+		envSet:          true,
+		envValue:        "TLS10",
+		expectedVersion: tls.VersionTLS10,
+	},
+	{
+		envSet:          true,
+		envValue:        "TLS11",
+		expectedVersion: tls.VersionTLS11,
+	},
+	{
+		envSet:          true,
+		envValue:        "TLS12",
+		expectedVersion: tls.VersionTLS12,
+	},
+	{
+		envSet:          true,
+		envValue:        "TLS13",
+		expectedVersion: tls.VersionTLS13,
+	},
+	{
+		envSet:          false,
+		expectedVersion: tls.VersionTLS12,
+	},
+}
+
+func TestResolveMinTLSVersion(t *testing.T) {
+	defer os.Unsetenv("KEDA_HTTP_MIN_TLS_VERSION")
+	for _, testData := range minTLSVersionTestDatas {
+		os.Unsetenv("KEDA_HTTP_MIN_TLS_VERSION")
+		if testData.envSet {
+			os.Setenv("KEDA_HTTP_MIN_TLS_VERSION", testData.envValue)
+		}
+		minVersion := initMinTLSVersion(logr.Discard())
+
+		if testData.expectedVersion != minVersion {
+			t.Error("Failed to resolve minTLSVersion correctly", "wants", testData.expectedVersion, "got", minVersion)
+		}
+	}
+}

From ff7a6233ec65ae3177740fa4425dc5f254564ab0 Mon Sep 17 00:00:00 2001
From: Jorge Turrado <jorge_turrado@hotmail.es>
Date: Thu, 9 Feb 2023 22:37:01 +0100
Subject: [PATCH 5/8] fix styles

Signed-off-by: Jorge Turrado <jorge_turrado@hotmail.es>
---
 config/e2e/create_cas_volume.yml    |  2 +-
 pkg/scalers/elasticsearch_scaler.go |  3 +-
 pkg/scalers/influxdb_scaler.go      |  5 +-
 pkg/scalers/redis_scaler.go         |  3 +-
 pkg/util/certificates.go            | 26 +++++---
 pkg/util/certificates_test.go       | 98 +++++++++++++++++++++++++++++
 pkg/util/http.go                    |  1 -
 7 files changed, 119 insertions(+), 19 deletions(-)
 create mode 100644 pkg/util/certificates_test.go

diff --git a/config/e2e/create_cas_volume.yml b/config/e2e/create_cas_volume.yml
index a28cbbd440c..fb596f92554 100644
--- a/config/e2e/create_cas_volume.yml
+++ b/config/e2e/create_cas_volume.yml
@@ -2,7 +2,7 @@
   path: /spec/template/spec/containers/0/volumeMounts/1
   value:
     name: custom-cas
-    mountPath: /custom-cas
+    mountPath: /custom/ca
     readOnly: true
 
 - op: add
diff --git a/pkg/scalers/elasticsearch_scaler.go b/pkg/scalers/elasticsearch_scaler.go
index 25929ca678c..932a187207f 100644
--- a/pkg/scalers/elasticsearch_scaler.go
+++ b/pkg/scalers/elasticsearch_scaler.go
@@ -17,7 +17,6 @@ import (
 	"k8s.io/metrics/pkg/apis/external_metrics"
 
 	"github.com/kedacore/keda/v2/pkg/util"
-	kedautil "github.com/kedacore/keda/v2/pkg/util"
 )
 
 type elasticsearchScaler struct {
@@ -217,7 +216,7 @@ func parseElasticsearchMetadata(config *ScalerConfig) (*elasticsearchMetadata, e
 		meta.activationTargetValue = activationTargetValue
 	}
 
-	meta.metricName = GenerateMetricNameWithIndex(config.ScalerIndex, kedautil.NormalizeString(fmt.Sprintf("elasticsearch-%s", meta.searchTemplateName)))
+	meta.metricName = GenerateMetricNameWithIndex(config.ScalerIndex, util.NormalizeString(fmt.Sprintf("elasticsearch-%s", meta.searchTemplateName)))
 	return &meta, nil
 }
 
diff --git a/pkg/scalers/influxdb_scaler.go b/pkg/scalers/influxdb_scaler.go
index 781ad016b8a..bc59ac3ee9e 100644
--- a/pkg/scalers/influxdb_scaler.go
+++ b/pkg/scalers/influxdb_scaler.go
@@ -12,7 +12,6 @@ import (
 	"k8s.io/metrics/pkg/apis/external_metrics"
 
 	"github.com/kedacore/keda/v2/pkg/util"
-	kedautil "github.com/kedacore/keda/v2/pkg/util"
 )
 
 type influxDBScaler struct {
@@ -120,9 +119,9 @@ func parseInfluxDBMetadata(config *ScalerConfig) (*influxDBMetadata, error) {
 	}
 
 	if val, ok := config.TriggerMetadata["metricName"]; ok {
-		metricName = kedautil.NormalizeString(fmt.Sprintf("influxdb-%s", val))
+		metricName = util.NormalizeString(fmt.Sprintf("influxdb-%s", val))
 	} else {
-		metricName = kedautil.NormalizeString(fmt.Sprintf("influxdb-%s", organizationName))
+		metricName = util.NormalizeString(fmt.Sprintf("influxdb-%s", organizationName))
 	}
 
 	if val, ok := config.TriggerMetadata["activationThresholdValue"]; ok {
diff --git a/pkg/scalers/redis_scaler.go b/pkg/scalers/redis_scaler.go
index 9e96ee7562c..f80a53baeed 100644
--- a/pkg/scalers/redis_scaler.go
+++ b/pkg/scalers/redis_scaler.go
@@ -14,7 +14,6 @@ import (
 	"k8s.io/metrics/pkg/apis/external_metrics"
 
 	"github.com/kedacore/keda/v2/pkg/util"
-	kedautil "github.com/kedacore/keda/v2/pkg/util"
 )
 
 const (
@@ -258,7 +257,7 @@ func (s *redisScaler) Close(context.Context) error {
 
 // GetMetricSpecForScaling returns the metric spec for the HPA
 func (s *redisScaler) GetMetricSpecForScaling(context.Context) []v2.MetricSpec {
-	metricName := kedautil.NormalizeString(fmt.Sprintf("redis-%s", s.metadata.listName))
+	metricName := util.NormalizeString(fmt.Sprintf("redis-%s", s.metadata.listName))
 	externalMetric := &v2.ExternalMetricSource{
 		Metric: v2.MetricIdentifier{
 			Name: GenerateMetricNameWithIndex(s.metadata.scalerIndex, metricName),
diff --git a/pkg/util/certificates.go b/pkg/util/certificates.go
index 356bb3ec1d3..d47e2245094 100644
--- a/pkg/util/certificates.go
+++ b/pkg/util/certificates.go
@@ -25,21 +25,31 @@ import (
 	logf "sigs.k8s.io/controller-runtime/pkg/log"
 )
 
-const customCAPath = "/custom-cas"
+const customCAPath = "/custom/ca"
 
 var logger = logf.Log.WithName("certificates")
 
 var rootCAs *x509.CertPool
 
-func init() {
-	certPool, _ := x509.SystemCertPool()
-	if certPool == nil {
-		certPool = x509.NewCertPool()
+func getRootCAs() *x509.CertPool {
+	if rootCAs != nil {
+		return rootCAs.Clone()
+	}
+
+	rootCAs, _ = x509.SystemCertPool()
+	if rootCAs == nil {
+		rootCAs = x509.NewCertPool()
+	}
+
+	if _, err := os.Stat(customCAPath); os.IsNotExist(err) {
+		logger.V(1).Info(fmt.Sprintf("the path %s doesn't exist, skipping custom CA registrations", customCAPath))
+		return rootCAs.Clone()
 	}
 
 	files, err := os.ReadDir(customCAPath)
 	if err != nil {
 		logger.Error(err, fmt.Sprintf("unable to read %s", customCAPath))
+		return rootCAs.Clone()
 	}
 
 	for _, file := range files {
@@ -52,15 +62,11 @@ func init() {
 			logger.Error(err, fmt.Sprintf("Failed to append %q to certPool", file.Name()))
 		}
 
-		if ok := certPool.AppendCertsFromPEM(certs); !ok {
+		if ok := rootCAs.AppendCertsFromPEM(certs); !ok {
 			logger.Error(fmt.Errorf("no certs appended"), fmt.Sprintf("the certificate %s hasn't been added to the pool", file.Name()))
 		}
 		logger.V(1).Info(fmt.Sprintf("the certificate %s has been added to the pool", file.Name()))
 	}
 
-	rootCAs = certPool
-}
-
-func getRootCAs() *x509.CertPool {
 	return rootCAs.Clone()
 }
diff --git a/pkg/util/certificates_test.go b/pkg/util/certificates_test.go
new file mode 100644
index 00000000000..221edaa65d8
--- /dev/null
+++ b/pkg/util/certificates_test.go
@@ -0,0 +1,98 @@
+/*
+Copyright 2023 The KEDA Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package util
+
+import (
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/x509"
+	"crypto/x509/pkix"
+	"encoding/asn1"
+	"encoding/pem"
+	"math/big"
+	"os"
+	"path"
+	"testing"
+	"time"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+var (
+	caCrtPath      = path.Join(customCAPath, "ca.crt")
+	certCommonName = "test-cert"
+)
+
+func TestCustomCAsAreRegistered(t *testing.T) {
+	defer os.Remove(caCrtPath)
+	generateCA(t)
+
+	rootCAs := getRootCAs()
+	//nolint:staticcheck // func (s *CertPool) Subjects was deprecated if s was returned by SystemCertPool, Subjects
+	subjects := rootCAs.Subjects()
+	var rdnSequence pkix.RDNSequence
+	_, err := asn1.Unmarshal(subjects[len(subjects)-1], &rdnSequence)
+	if err != nil {
+		t.Fatal("could not unmarshal der formatted subject")
+	}
+	var name pkix.Name
+	name.FillFromRDNSequence(&rdnSequence)
+
+	assert.Equal(t, certCommonName, name.CommonName, "certificate not found")
+}
+
+func generateCA(t *testing.T) {
+	err := os.MkdirAll(customCAPath, os.ModePerm)
+	require.NoErrorf(t, err, "error generating the custom ca folder - %s", err)
+
+	ca := &x509.Certificate{
+		SerialNumber: big.NewInt(2019),
+		Subject: pkix.Name{
+			Organization:  []string{"Company, INC."},
+			Country:       []string{"US"},
+			Province:      []string{""},
+			Locality:      []string{"San Francisco"},
+			StreetAddress: []string{"Golden Gate Bridge"},
+			PostalCode:    []string{"94016"},
+			CommonName:    certCommonName,
+		},
+		NotBefore:             time.Now(),
+		NotAfter:              time.Now().AddDate(10, 0, 0),
+		IsCA:                  true,
+		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
+		KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
+		BasicConstraintsValid: true,
+	}
+
+	// create our private and public key
+	caPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
+	require.NoErrorf(t, err, "error generating custom CA key - %s", err)
+
+	// create the CA
+	caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &caPrivKey.PublicKey, caPrivKey)
+	require.NoErrorf(t, err, "error generating custom CA - %s", err)
+
+	// pem encode
+	crtFile, err := os.OpenFile(caCrtPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
+	require.NoErrorf(t, err, "error opening custom CA file - %s", err)
+	err = pem.Encode(crtFile, &pem.Block{
+		Type:  "CERTIFICATE",
+		Bytes: caBytes,
+	})
+	require.NoErrorf(t, err, "error opening custom CA file - %s", err)
+}
diff --git a/pkg/util/http.go b/pkg/util/http.go
index 25a0e9d74c1..d0d12878201 100644
--- a/pkg/util/http.go
+++ b/pkg/util/http.go
@@ -36,7 +36,6 @@ func init() {
 
 func init() {
 	disableKeepAlives = getKeepAliveValue()
-	rootCAs = getRootCAs()
 }
 
 func getKeepAliveValue() bool {

From 19fe05ebce9e75b14487ae4ebf39eb3a7bd00252 Mon Sep 17 00:00:00 2001
From: Jorge Turrado <jorge_turrado@hotmail.es>
Date: Thu, 9 Feb 2023 22:43:41 +0100
Subject: [PATCH 6/8] use proper error checking

Signed-off-by: Jorge Turrado <jorge_turrado@hotmail.es>
---
 pkg/util/certificates.go | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/pkg/util/certificates.go b/pkg/util/certificates.go
index d47e2245094..ed5be75ecaa 100644
--- a/pkg/util/certificates.go
+++ b/pkg/util/certificates.go
@@ -18,7 +18,9 @@ package util
 
 import (
 	"crypto/x509"
+	"errors"
 	"fmt"
+	"io/fs"
 	"os"
 	"path"
 
@@ -41,7 +43,7 @@ func getRootCAs() *x509.CertPool {
 		rootCAs = x509.NewCertPool()
 	}
 
-	if _, err := os.Stat(customCAPath); os.IsNotExist(err) {
+	if _, err := os.Stat(customCAPath); errors.Is(err, fs.ErrNotExist) {
 		logger.V(1).Info(fmt.Sprintf("the path %s doesn't exist, skipping custom CA registrations", customCAPath))
 		return rootCAs.Clone()
 	}

From a47f71fa5d4e008ecd1ae9cf01a5c4805502efc7 Mon Sep 17 00:00:00 2001
From: Jorge Turrado <jorge_turrado@hotmail.es>
Date: Fri, 10 Feb 2023 01:35:23 +0100
Subject: [PATCH 7/8] add unit tests

Signed-off-by: Jorge Turrado <jorge_turrado@hotmail.es>
---
 pkg/util/http_test.go | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 pkg/util/http_test.go

diff --git a/pkg/util/http_test.go b/pkg/util/http_test.go
new file mode 100644
index 00000000000..f33da81192d
--- /dev/null
+++ b/pkg/util/http_test.go
@@ -0,0 +1,36 @@
+/*
+Copyright 2023 The KEDA Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package util
+
+import (
+	"testing"
+	"time"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestCreateHTTPClientWhenNegativeTimeout(t *testing.T) {
+	client := CreateHTTPClient(-1*time.Minute, false)
+
+	assert.Equal(t, 300*time.Millisecond, client.Timeout)
+}
+
+func TestCreateHTTPClientWhenValidTimeout(t *testing.T) {
+	client := CreateHTTPClient(1*time.Minute, false)
+
+	assert.Equal(t, 1*time.Minute, client.Timeout)
+}

From 93429e80036714d32f965e902caaa1f5e3d0ed4f Mon Sep 17 00:00:00 2001
From: Jorge Turrado <jorge_turrado@hotmail.es>
Date: Sun, 12 Feb 2023 14:19:50 +0100
Subject: [PATCH 8/8] fix tests

Signed-off-by: Jorge Turrado <jorge_turrado@hotmail.es>
---
 pkg/util/tls_config_test.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/pkg/util/tls_config_test.go b/pkg/util/tls_config_test.go
index 8d9ea2edd1e..18b8513ef1a 100644
--- a/pkg/util/tls_config_test.go
+++ b/pkg/util/tls_config_test.go
@@ -166,7 +166,7 @@ func TestNewTLSConfig_WithoutPassword(t *testing.T) {
 			}
 
 			if test.CACert != "" {
-				caCertPool := x509.NewCertPool()
+				caCertPool := getRootCAs()
 				caCertPool.AppendCertsFromPEM([]byte(randomCACert))
 				if !config.RootCAs.Equal(caCertPool) {
 					t.Errorf("TLS config return different CA cert")
@@ -233,7 +233,7 @@ func TestNewTLSConfig_WithPassword(t *testing.T) {
 			}
 
 			if test.CACert != "" {
-				caCertPool := x509.NewCertPool()
+				caCertPool := getRootCAs()
 				caCertPool.AppendCertsFromPEM([]byte(randomCACert))
 				if !config.RootCAs.Equal(caCertPool) {
 					t.Errorf("TLS config return different CA cert")