@@ -1364,6 +1364,144 @@ var _ = Describe("With a running MachineSync Reconciler", func() {
13641364
13651365 })
13661366
1367+ Context ("Updates to MAPI machine warns user if the Synchronized condition is set to false" , func () {
1368+ var warnClient client.Client
1369+ var warnSink * admissiontestutils.WarningCollector
1370+ var warnKomega komega.Komega
1371+
1372+ BeforeEach (func () {
1373+ By ("Waiting for VAP to be ready" )
1374+ machineVap = & admissionregistrationv1.ValidatingAdmissionPolicy {}
1375+ Eventually (k8sClient .Get (ctx , client.ObjectKey {Name : "openshift-provide-warning-when-not-synchronized" }, machineVap ), timeout ).Should (Succeed ())
1376+ Eventually (k .Update (machineVap , func () {
1377+ machineVap .Spec .Validations = append (machineVap .Spec .Validations , admissionregistrationv1.Validation {
1378+ Expression : "!(has(object.metadata.labels) && \" test-sentinel\" in object.metadata.labels)" ,
1379+ Message : "policy in place" ,
1380+ })
1381+ })).Should (Succeed ())
1382+
1383+ Eventually (k .Object (machineVap ), timeout ).Should (
1384+ HaveField ("Status.ObservedGeneration" , BeNumerically (">=" , 2 )),
1385+ )
1386+
1387+ By ("Updating the VAP binding" )
1388+ policyBinding = & admissionregistrationv1.ValidatingAdmissionPolicyBinding {}
1389+ Eventually (k8sClient .Get (ctx , client.ObjectKey {
1390+ Name : "openshift-provide-warning-when-not-synchronized" }, policyBinding ), timeout ).Should (Succeed ())
1391+
1392+ Eventually (k .Update (policyBinding , func () {
1393+ // We need to update the namespace in our namespaceSelector,
1394+ // since also use `GenerateName` here
1395+ policyBinding .Spec .MatchResources .NamespaceSelector .MatchLabels = map [string ]string {
1396+ "kubernetes.io/metadata.name" : mapiNamespace .GetName (),
1397+ }
1398+ }), timeout ).Should (Succeed ())
1399+
1400+ // Wait until the binding shows the patched values
1401+ Eventually (k .Object (policyBinding ), timeout ).Should (
1402+ SatisfyAll (
1403+ HaveField ("Spec.MatchResources.NamespaceSelector.MatchLabels" ,
1404+ HaveKeyWithValue ("kubernetes.io/metadata.name" ,
1405+ mapiNamespace .GetName ())),
1406+ ),
1407+ )
1408+
1409+ By ("Creating a throwaway MAPI machine" )
1410+ sentinelMachine := mapiMachineBuilder .WithName ("sentinel-machine" ).WithAuthoritativeAPI (mapiv1beta1 .MachineAuthorityClusterAPI ).Build ()
1411+ Eventually (k8sClient .Create (ctx , sentinelMachine ), timeout ).Should (Succeed ())
1412+
1413+ var err error
1414+ warnClient , warnSink , err = admissiontestutils .SetupClientWithWarningCollector (cfg , testScheme )
1415+ Expect (err ).To (Not (HaveOccurred ()))
1416+
1417+ warnKomega = komega .New (warnClient )
1418+
1419+ Eventually (func (g Gomega ) {
1420+ warnSink .Reset () // keep each probe self-contained
1421+
1422+ err := warnKomega .Update (sentinelMachine , func () {
1423+ sentinelMachine .ObjectMeta .Labels = map [string ]string {"test-sentinel" : "fubar" }
1424+ })()
1425+ g .Expect (err ).NotTo (HaveOccurred ())
1426+
1427+ g .Expect (warnSink .Messages ()).To (ContainElement (ContainSubstring ("policy in place" )))
1428+ }, timeout ).Should (Succeed ())
1429+
1430+ })
1431+
1432+ It ("warns the user when the machine is still synchronizing" , func () {
1433+ By ("Setting the Synchronized condition to False" )
1434+ Eventually (k .UpdateStatus (mapiMachine , func () {
1435+ mapiMachine .Status .Conditions = []mapiv1beta1.Condition {
1436+ {
1437+ Type : consts .SynchronizedCondition ,
1438+ Status : corev1 .ConditionFalse ,
1439+ Reason : "ErrorReason" ,
1440+ Message : "Error message" ,
1441+ LastTransitionTime : metav1 .Now (),
1442+ },
1443+ }
1444+ })).Should (Succeed ())
1445+
1446+ By ("Attempting to update the authoritativeAPI should emit a warning" )
1447+ Eventually (func (g Gomega ) {
1448+ warnSink .Reset () // keep each probe self-contained
1449+
1450+ err := warnKomega .Update (mapiMachine , func () {
1451+ mapiMachine .Spec .AuthoritativeAPI = mapiv1beta1 .MachineAuthorityClusterAPI
1452+ })()
1453+ g .Expect (err ).NotTo (HaveOccurred ())
1454+
1455+ g .Expect (warnSink .Messages ()).To (ContainElement (ContainSubstring ("Updating .spec.authoritativeAPI when the Synchronized condition is not true means changes may not take effect" )))
1456+ }, timeout ).Should (Succeed ())
1457+ })
1458+ It ("warns the user when the machine synchronisation is unknown" , func () {
1459+ By ("Setting the Synchronized condition to Unknown" )
1460+ Eventually (k .UpdateStatus (mapiMachine , func () {
1461+ mapiMachine .Status .Conditions = []mapiv1beta1.Condition {
1462+ {
1463+ Type : consts .SynchronizedCondition ,
1464+ Status : corev1 .ConditionUnknown ,
1465+ Reason : "ErrorReason" ,
1466+ Message : "Error message" ,
1467+ LastTransitionTime : metav1 .Now (),
1468+ },
1469+ }
1470+ })).Should (Succeed ())
1471+
1472+ By ("Attempting to update the authoritativeAPI should emit a warning" )
1473+ Eventually (func (g Gomega ) {
1474+ warnSink .Reset () // keep each probe self-contained
1475+
1476+ err := warnKomega .Update (mapiMachine , func () {
1477+ mapiMachine .Spec .AuthoritativeAPI = mapiv1beta1 .MachineAuthorityClusterAPI
1478+ })()
1479+ g .Expect (err ).NotTo (HaveOccurred ())
1480+
1481+ g .Expect (warnSink .Messages ()).To (ContainElement (ContainSubstring ("Updating .spec.authoritativeAPI when the Synchronized condition is not true means changes may not take effect" )))
1482+ }, timeout ).Should (Succeed ())
1483+ })
1484+
1485+ It ("warns the user when the machine has no synchronized condition" , func () {
1486+ By ("Setting the conditions to empty" )
1487+ Eventually (k .UpdateStatus (mapiMachine , func () {
1488+ mapiMachine .Status .Conditions = []mapiv1beta1.Condition {}
1489+ })).Should (Succeed ())
1490+
1491+ By ("Attempting to update the authoritativeAPI should emit a warning" )
1492+ Eventually (func (g Gomega ) {
1493+ warnSink .Reset () // keep each probe self-contained
1494+
1495+ err := warnKomega .Update (mapiMachine , func () {
1496+ mapiMachine .Spec .AuthoritativeAPI = mapiv1beta1 .MachineAuthorityClusterAPI
1497+ })()
1498+ g .Expect (err ).NotTo (HaveOccurred ())
1499+
1500+ g .Expect (warnSink .Messages ()).To (ContainElement (ContainSubstring ("Updating .spec.authoritativeAPI when the Synchronized condition is not true means changes may not take effect" )))
1501+ }, timeout ).Should (Succeed ())
1502+ })
1503+ })
1504+
13671505 })
13681506})
13691507
0 commit comments