@@ -18,6 +18,7 @@ package controllers
1818
1919import (
2020 "context"
21+ "fmt"
2122 "strings"
2223 "testing"
2324
@@ -914,3 +915,246 @@ func trimSpaces(s string) string {
914915 s = strings .ReplaceAll (s , "\t " , "" )
915916 return s
916917}
918+
919+ func TestEmitCertificateRenewalTriggeredEvent (t * testing.T ) {
920+ tests := []struct {
921+ name string
922+ machinesUpToDateResults map [string ]internal.UpToDateResult
923+ rollingOutCondition * metav1.Condition
924+ v1beta1Condition * clusterv1.Condition
925+ certificatesExpiryDays int32
926+ expectedEventCount int
927+ expectedEventReason string
928+ expectedMachinesInEvent []string
929+ expectedDaysInEvent int32
930+ }{
931+ {
932+ name : "should emit event when certificate renewal is detected for the first time" ,
933+ machinesUpToDateResults : map [string ]internal.UpToDateResult {
934+ "machine-1" : {
935+ ConditionMessages : []string {
936+ "Certificates will expire soon" ,
937+ },
938+ },
939+ },
940+ rollingOutCondition : nil , // No RollingOut condition exists yet
941+ v1beta1Condition : nil , // No v1beta1 condition exists yet
942+ certificatesExpiryDays : 30 ,
943+ expectedEventCount : 1 ,
944+ expectedEventReason : "CertificatesExpiring" ,
945+ expectedMachinesInEvent : []string {"machine-1" },
946+ expectedDaysInEvent : 30 ,
947+ },
948+ {
949+ name : "should emit event for multiple machines" ,
950+ machinesUpToDateResults : map [string ]internal.UpToDateResult {
951+ "machine-1" : {
952+ ConditionMessages : []string {
953+ "Certificates will expire soon" ,
954+ },
955+ },
956+ "machine-2" : {
957+ ConditionMessages : []string {
958+ "Certificates will expire soon" ,
959+ },
960+ },
961+ },
962+ rollingOutCondition : nil ,
963+ v1beta1Condition : nil ,
964+ certificatesExpiryDays : 30 ,
965+ expectedEventCount : 1 ,
966+ expectedEventReason : "CertificatesExpiring" ,
967+ expectedMachinesInEvent : []string {"machine-1" , "machine-2" },
968+ expectedDaysInEvent : 30 ,
969+ },
970+ {
971+ name : "should not emit event when already rolling out (v2 RollingOutCondition=True)" ,
972+ machinesUpToDateResults : map [string ]internal.UpToDateResult {
973+ "machine-1" : {
974+ ConditionMessages : []string {
975+ "Certificates will expire soon" ,
976+ },
977+ },
978+ },
979+ rollingOutCondition : & metav1.Condition {
980+ Type : controlplanev1 .KubeadmControlPlaneRollingOutCondition ,
981+ Status : metav1 .ConditionTrue ,
982+ },
983+ v1beta1Condition : nil ,
984+ certificatesExpiryDays : 30 ,
985+ expectedEventCount : 0 ,
986+ },
987+ {
988+ name : "should not emit event when already rolling out (v1beta1 MachinesSpecUpToDate=False)" ,
989+ machinesUpToDateResults : map [string ]internal.UpToDateResult {
990+ "machine-1" : {
991+ ConditionMessages : []string {
992+ "Certificates will expire soon" ,
993+ },
994+ },
995+ },
996+ rollingOutCondition : nil ,
997+ v1beta1Condition : & clusterv1.Condition {
998+ Type : controlplanev1 .MachinesSpecUpToDateV1Beta1Condition ,
999+ Status : corev1 .ConditionFalse ,
1000+ },
1001+ certificatesExpiryDays : 30 ,
1002+ expectedEventCount : 0 ,
1003+ },
1004+ {
1005+ name : "should not emit event when no certificate renewal detected" ,
1006+ machinesUpToDateResults : map [string ]internal.UpToDateResult {
1007+ "machine-1" : {
1008+ ConditionMessages : []string {
1009+ "Version mismatch" ,
1010+ },
1011+ },
1012+ },
1013+ rollingOutCondition : nil ,
1014+ v1beta1Condition : nil ,
1015+ certificatesExpiryDays : 30 ,
1016+ expectedEventCount : 0 ,
1017+ },
1018+ {
1019+ name : "should not emit event when no machines need rollout" ,
1020+ machinesUpToDateResults : map [string ]internal.UpToDateResult {},
1021+ rollingOutCondition : nil ,
1022+ v1beta1Condition : nil ,
1023+ certificatesExpiryDays : 30 ,
1024+ expectedEventCount : 0 ,
1025+ },
1026+ {
1027+ name : "should emit CertificatesExpired event when certificates have already expired" ,
1028+ machinesUpToDateResults : map [string ]internal.UpToDateResult {
1029+ "machine-1" : {
1030+ ConditionMessages : []string {
1031+ "KubeadmControlPlane spec.rolloutAfter expired" ,
1032+ },
1033+ },
1034+ },
1035+ rollingOutCondition : nil ,
1036+ v1beta1Condition : nil ,
1037+ certificatesExpiryDays : 30 ,
1038+ expectedEventCount : 1 ,
1039+ expectedEventReason : "CertificatesExpired" ,
1040+ expectedMachinesInEvent : []string {"machine-1" },
1041+ },
1042+ {
1043+ name : "should emit CertificatesExpired event for multiple machines with expired certificates" ,
1044+ machinesUpToDateResults : map [string ]internal.UpToDateResult {
1045+ "machine-1" : {
1046+ ConditionMessages : []string {
1047+ "KubeadmControlPlane spec.rolloutAfter expired" ,
1048+ },
1049+ },
1050+ "machine-2" : {
1051+ ConditionMessages : []string {
1052+ "KubeadmControlPlane spec.rolloutAfter expired" ,
1053+ },
1054+ },
1055+ },
1056+ rollingOutCondition : nil ,
1057+ v1beta1Condition : nil ,
1058+ certificatesExpiryDays : 30 ,
1059+ expectedEventCount : 1 ,
1060+ expectedEventReason : "CertificatesExpired" ,
1061+ expectedMachinesInEvent : []string {"machine-1" , "machine-2" },
1062+ },
1063+ {
1064+ name : "should emit both events when some certificates are expiring and some have expired" ,
1065+ machinesUpToDateResults : map [string ]internal.UpToDateResult {
1066+ "machine-1" : {
1067+ ConditionMessages : []string {
1068+ "Certificates will expire soon" ,
1069+ },
1070+ },
1071+ "machine-2" : {
1072+ ConditionMessages : []string {
1073+ "KubeadmControlPlane spec.rolloutAfter expired" ,
1074+ },
1075+ },
1076+ },
1077+ rollingOutCondition : nil ,
1078+ v1beta1Condition : nil ,
1079+ certificatesExpiryDays : 30 ,
1080+ expectedEventCount : 2 ,
1081+ expectedEventReason : "CertificatesExpiring" , // First event reason
1082+ expectedMachinesInEvent : []string {"machine-1" , "machine-2" },
1083+ expectedDaysInEvent : 30 ,
1084+ },
1085+ }
1086+
1087+ for _ , tt := range tests {
1088+ t .Run (tt .name , func (t * testing.T ) {
1089+ g := NewWithT (t )
1090+
1091+ // Create a fake event recorder
1092+ fakeRecorder := record .NewFakeRecorder (10 )
1093+
1094+ // Create KCP with certificate expiry days
1095+ kcp := & controlplanev1.KubeadmControlPlane {
1096+ ObjectMeta : metav1.ObjectMeta {
1097+ Name : "test-kcp" ,
1098+ Namespace : metav1 .NamespaceDefault ,
1099+ },
1100+ Spec : controlplanev1.KubeadmControlPlaneSpec {
1101+ Rollout : controlplanev1.KubeadmControlPlaneRolloutSpec {
1102+ Before : controlplanev1.KubeadmControlPlaneRolloutBeforeSpec {
1103+ CertificatesExpiryDays : tt .certificatesExpiryDays ,
1104+ },
1105+ },
1106+ },
1107+ }
1108+
1109+ if tt .rollingOutCondition != nil {
1110+ kcp .Status .Conditions = []metav1.Condition {* tt .rollingOutCondition }
1111+ }
1112+ if tt .v1beta1Condition != nil {
1113+ kcp .SetV1Beta1Conditions ([]clusterv1.Condition {* tt .v1beta1Condition })
1114+ }
1115+
1116+ // Create control plane
1117+ controlPlane := & internal.ControlPlane {
1118+ KCP : kcp ,
1119+ }
1120+
1121+ // Create reconciler with fake recorder
1122+ r := & KubeadmControlPlaneReconciler {
1123+ recorder : fakeRecorder ,
1124+ }
1125+
1126+ // Call the function
1127+ r .emitCertificateRenewalTriggeredEvent (context .Background (), controlPlane , tt .machinesUpToDateResults )
1128+
1129+ // Verify events
1130+ events := []string {}
1131+ close (fakeRecorder .Events )
1132+ for event := range fakeRecorder .Events {
1133+ events = append (events , event )
1134+ }
1135+
1136+ g .Expect (events ).To (HaveLen (tt .expectedEventCount ))
1137+ if tt .expectedEventCount > 0 {
1138+ // Verify event reason
1139+ g .Expect (events [0 ]).To (ContainSubstring (tt .expectedEventReason ))
1140+
1141+ // For CertificatesExpiring events, verify days threshold
1142+ if tt .expectedEventReason == "CertificatesExpiring" {
1143+ g .Expect (events [0 ]).To (ContainSubstring ("certificates expiring within" ))
1144+ g .Expect (events [0 ]).To (ContainSubstring (fmt .Sprintf ("%d days" , tt .expectedDaysInEvent )))
1145+ }
1146+
1147+ // For CertificatesExpired events, verify expired message
1148+ if tt .expectedEventReason == "CertificatesExpired" {
1149+ g .Expect (events [0 ]).To (ContainSubstring ("expired certificates" ))
1150+ }
1151+
1152+ // Verify machines are mentioned in events
1153+ allEvents := strings .Join (events , " " )
1154+ for _ , machine := range tt .expectedMachinesInEvent {
1155+ g .Expect (allEvents ).To (ContainSubstring (machine ))
1156+ }
1157+ }
1158+ })
1159+ }
1160+ }
0 commit comments