@@ -1876,6 +1876,115 @@ var _ = Describe("With a running MachineSync Reconciler", func() {
18761876 })
18771877 })
18781878
1879+ FContext ("cluster api machine validation" , func () {
1880+ var vapName = "openshift-validate-capi-machine-creation"
1881+
1882+ BeforeEach (func () {
1883+ By ("Waiting for VAP to be ready" )
1884+ machineVap = & admissionregistrationv1.ValidatingAdmissionPolicy {}
1885+ Eventually (k8sClient .Get (ctx , client.ObjectKey {Name : vapName }, machineVap ), timeout ).Should (Succeed ())
1886+ Eventually (k .Update (machineVap , func () {
1887+ admissiontestutils .AddSentinelValidation (machineVap )
1888+ })).Should (Succeed ())
1889+
1890+ Eventually (k .Object (machineVap ), timeout ).Should (
1891+ HaveField ("Status.ObservedGeneration" , BeNumerically (">=" , 2 )),
1892+ )
1893+
1894+ By ("Updating the VAP binding" )
1895+ policyBinding = & admissionregistrationv1.ValidatingAdmissionPolicyBinding {}
1896+ Eventually (k8sClient .Get (ctx , client.ObjectKey {
1897+ Name : vapName }, policyBinding ), timeout ).Should (Succeed ())
1898+
1899+ Eventually (k .Update (policyBinding , func () {
1900+ admissiontestutils .UpdateVAPBindingNamespaces (policyBinding , mapiNamespace .GetName (), capiNamespace .GetName ())
1901+ }), timeout ).Should (Succeed ())
1902+
1903+ // Wait until the binding shows the patched values
1904+ Eventually (k .Object (policyBinding ), timeout ).Should (
1905+ SatisfyAll (
1906+ HaveField ("Spec.ParamRef.Namespace" ,
1907+ Equal (mapiNamespace .GetName ())),
1908+
1909+ HaveField ("Spec.MatchResources.NamespaceSelector.MatchLabels" ,
1910+ HaveKeyWithValue ("kubernetes.io/metadata.name" ,
1911+ capiNamespace .GetName ())),
1912+ ),
1913+ )
1914+
1915+ By ("Creating the sentinel CAPI infra machine" )
1916+ capaMachine = capaMachineBuilder .WithName ("sentinel-machine" ).Build ()
1917+ Eventually (k8sClient .Create (ctx , capaMachine )).Should (Succeed (), "capa machine should be able to be created" )
1918+
1919+ capaMachineRef := corev1.ObjectReference {
1920+ Kind : capaMachine .Kind ,
1921+ Name : capaMachine .GetName (),
1922+ Namespace : capaMachine .GetNamespace (),
1923+ }
1924+
1925+ By ("Creating a sentinel CAPI machine" )
1926+ testMachine := capiMachineBuilder .WithName ("sentinel-machine" ).WithInfrastructureRef (capaMachineRef ).Build ()
1927+ Eventually (k8sClient .Create (ctx , testMachine ), timeout ).Should (Succeed ())
1928+
1929+ By ("setting the owner reference on the sentinel CAPI infra machine" )
1930+ Eventually (k .Update (capaMachine , func () {
1931+ capaMachine .SetOwnerReferences ([]metav1.OwnerReference {
1932+ {
1933+ Kind : machineKind ,
1934+ APIVersion : clusterv1 .GroupVersion .String (),
1935+ Name : testMachine .Name ,
1936+ UID : testMachine .UID ,
1937+ BlockOwnerDeletion : ptr .To (true ),
1938+ Controller : ptr .To (false ),
1939+ },
1940+ })
1941+ })).Should (Succeed ())
1942+
1943+ By ("Creating a sentinel MAPI Machine" )
1944+ testMapiMachine := mapiMachineBuilder .WithName (testMachine .Name ).Build ()
1945+ Eventually (k8sClient .Create (ctx , testMapiMachine ), timeout ).Should (Succeed ())
1946+
1947+ By ("Setting the sentinel MAPI machine AuthoritativeAPI to Machine API" )
1948+ Eventually (k .UpdateStatus (testMapiMachine , func () {
1949+ testMapiMachine .Status .AuthoritativeAPI = mapiv1beta1 .MachineAuthorityMachineAPI
1950+ })).Should (Succeed ())
1951+
1952+ Eventually (k .Object (testMapiMachine ), timeout ).Should (
1953+ HaveField ("Status.AuthoritativeAPI" , Equal (mapiv1beta1 .MachineAuthorityMachineAPI )))
1954+
1955+ // The sync controller copies labels MAPI → CAPI. Labels under
1956+ // machine.openshift.io/* and cluster.x-k8s.io/* are controller-managed and
1957+ // write-protected by the labels rule. If we update before these labels are
1958+ // populated, our change can drop them and be rejected. Wait for sync, then add
1959+ // the test sentinel.
1960+
1961+ Eventually (k .Object (testMachine ), timeout ).Should (
1962+ HaveField ("ObjectMeta.Labels" , Not (BeNil ())),
1963+ )
1964+
1965+ Eventually (k .Update (testMachine , func () {
1966+ testMachine .ObjectMeta .Labels ["test-sentinel" ] = "fubar"
1967+ }), timeout ).Should (MatchError (ContainSubstring ("policy in place" )))
1968+ })
1969+
1970+ Context ("with status.authoritativeAPI: Machine API" , func () {
1971+ BeforeEach (func () {
1972+ By ("Setting the MAPI machine AuthoritativeAPI to Machine API" )
1973+ Eventually (k .UpdateStatus (mapiMachine , func () {
1974+ mapiMachine .Status .AuthoritativeAPI = mapiv1beta1 .MachineAuthorityMachineAPI
1975+ })).Should (Succeed ())
1976+
1977+ Eventually (k .Object (mapiMachine ), timeout ).Should (
1978+ HaveField ("Status.AuthoritativeAPI" , Equal (mapiv1beta1 .MachineAuthorityMachineAPI )))
1979+ })
1980+
1981+ It ("updating the spec should be prevented" , func () {
1982+ Eventually (k .Update (capiMachine , func () {
1983+ }), timeout ).Should (MatchError (ContainSubstring ("Changing .spec is not allowed" )))
1984+ })
1985+ })
1986+ })
1987+
18791988 })
18801989})
18811990
0 commit comments