Skip to content

Commit 0bd7db4

Browse files
committed
Add VPA admission-controller certificate reload e2e test
1 parent 4a53898 commit 0bd7db4

File tree

5 files changed

+67
-1
lines changed

5 files changed

+67
-1
lines changed

vertical-pod-autoscaler/deploy/admission-controller-deployment.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ spec:
2727
valueFrom:
2828
fieldRef:
2929
fieldPath: metadata.namespace
30+
args: ["--v=4", "--stderrthreshold=info", "--reload-cert"]
3031
volumeMounts:
3132
- name: tls-certs
3233
mountPath: "/etc/tls-certs"

vertical-pod-autoscaler/e2e/v1/admission_controller.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ package autoscaling
1919
import (
2020
"context"
2121
"fmt"
22+
"io"
23+
"strings"
2224
"time"
2325

2426
appsv1 "k8s.io/api/apps/v1"
@@ -852,6 +854,60 @@ var _ = AdmissionControllerE2eDescribe("Admission-controller", func() {
852854
gomega.Expect(err2.Error()).To(gomega.MatchRegexp(`.*admission webhook .*vpa.* denied the request: .*`))
853855
})
854856

857+
ginkgo.It("reloads the webhook certificate", func(ctx ginkgo.SpecContext) {
858+
ginkgo.By("Retrieving alternative certificate")
859+
c := f.ClientSet
860+
e2eCertsSecret, err := c.CoreV1().Secrets(metav1.NamespaceSystem).Get(ctx, "vpa-e2e-certs", metav1.GetOptions{})
861+
gomega.Expect(err).To(gomega.Succeed(), "Failed to get vpa-e2e-certs secret")
862+
actualCertsSecret, err := c.CoreV1().Secrets(metav1.NamespaceSystem).Get(ctx, "vpa-tls-certs", metav1.GetOptions{})
863+
gomega.Expect(err).To(gomega.Succeed(), "Failed to get vpa-tls-certs secret")
864+
actualCertsSecret.Data["serverKey.pem"] = e2eCertsSecret.Data["e2eKey.pem"]
865+
actualCertsSecret.Data["serverCert.pem"] = e2eCertsSecret.Data["e2eCert.pem"]
866+
_, err = c.CoreV1().Secrets(metav1.NamespaceSystem).Update(ctx, actualCertsSecret, metav1.UpdateOptions{})
867+
gomega.Expect(err).To(gomega.Succeed(), "Failed to update vpa-tls-certs secret with e2e rotation certs")
868+
869+
ginkgo.By("Waiting for certificate reload")
870+
pods, err := c.CoreV1().Pods(metav1.NamespaceSystem).List(ctx, metav1.ListOptions{})
871+
gomega.Expect(err).To(gomega.Succeed())
872+
873+
var admissionController apiv1.Pod
874+
for _, p := range pods.Items {
875+
if strings.HasPrefix(p.Name, "vpa-admission-controller") {
876+
admissionController = p
877+
}
878+
}
879+
gomega.Expect(admissionController.Name).ToNot(gomega.BeEmpty())
880+
881+
gomega.Eventually(func(g gomega.Gomega) string {
882+
reader, err := c.CoreV1().Pods(metav1.NamespaceSystem).GetLogs(admissionController.Name, &apiv1.PodLogOptions{}).Stream(ctx)
883+
g.Expect(err).To(gomega.Succeed())
884+
logs, err := io.ReadAll(reader)
885+
g.Expect(err).To(gomega.Succeed())
886+
return string(logs)
887+
}).Should(gomega.ContainSubstring("New certificate found, reloading"))
888+
889+
ginkgo.By("Setting up invalid VPA object")
890+
// there is an invalid "requests" field.
891+
invalidVPA := []byte(`{
892+
"kind": "VerticalPodAutoscaler",
893+
"apiVersion": "autoscaling.k8s.io/v1",
894+
"metadata": {"name": "cert-vpa-invalid"},
895+
"spec": {
896+
"targetRef": {
897+
"apiVersion": "apps/v1",
898+
"kind": "Deployment",
899+
"name":"hamster"
900+
},
901+
"resourcePolicy": {
902+
"containerPolicies": [{"containerName": "*", "minAllowed":{"requests":{"cpu":"50m"}}}]
903+
}
904+
}
905+
}`)
906+
err = InstallRawVPA(f, invalidVPA)
907+
gomega.Expect(err).To(gomega.HaveOccurred(), "Invalid VPA object accepted")
908+
gomega.Expect(err.Error()).To(gomega.MatchRegexp(`.*admission webhook .*vpa.* denied the request: .*`), "Admission controller did not inspect the object")
909+
})
910+
855911
})
856912

857913
func startDeploymentPods(f *framework.Framework, deployment *appsv1.Deployment) *apiv1.PodList {

vertical-pod-autoscaler/hack/deploy-for-e2e.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ gcloud auth configure-docker -q
6868

6969
for i in ${COMPONENTS}; do
7070
if [ $i == admission-controller ] ; then
71-
(cd ${SCRIPT_ROOT}/pkg/${i} && bash ./gencerts.sh || true)
71+
(cd ${SCRIPT_ROOT}/pkg/${i} && bash ./gencerts.sh e2e || true)
7272
fi
7373
ALL_ARCHITECTURES=amd64 make --directory ${SCRIPT_ROOT}/pkg/${i} release
7474
done

vertical-pod-autoscaler/pkg/admission-controller/gencerts.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ openssl x509 -req -in ${TMP_DIR}/server.csr -CA ${TMP_DIR}/caCert.pem -CAkey ${T
5757
echo "Uploading certs to the cluster."
5858
kubectl create secret --namespace=kube-system generic vpa-tls-certs --from-file=${TMP_DIR}/caKey.pem --from-file=${TMP_DIR}/caCert.pem --from-file=${TMP_DIR}/serverKey.pem --from-file=${TMP_DIR}/serverCert.pem
5959

60+
if [ "${1:-unset}" = "e2e" ]; then
61+
openssl genrsa -out ${TMP_DIR}/e2eKey.pem 2048
62+
openssl req -new -key ${TMP_DIR}/e2eKey.pem -out ${TMP_DIR}/e2e.csr -subj "/CN=vpa-webhook.kube-system.svc" -config ${TMP_DIR}/server.conf
63+
openssl x509 -req -in ${TMP_DIR}/e2e.csr -CA ${TMP_DIR}/caCert.pem -CAkey ${TMP_DIR}/caKey.pem -CAcreateserial -out ${TMP_DIR}/e2eCert.pem -days 100000 -extensions SAN -extensions v3_req -extfile ${TMP_DIR}/server.conf
64+
echo "Uploading rotation e2e test certs to the cluster."
65+
kubectl create secret --namespace=kube-system generic vpa-e2e-certs --from-file=${TMP_DIR}/e2eKey.pem --from-file=${TMP_DIR}/e2eCert.pem
66+
fi
67+
6068
# Clean up after we're done.
6169
echo "Deleting ${TMP_DIR}."
6270
rm -rf ${TMP_DIR}

vertical-pod-autoscaler/pkg/admission-controller/rmcerts.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ set -e
2121

2222
echo "Deleting VPA Admission Controller certs."
2323
kubectl delete secret --namespace=kube-system vpa-tls-certs
24+
kubectl delete secret --namespace=kube-system --ignore-not-found=true vpa-e2e-certs

0 commit comments

Comments
 (0)