44 "bytes"
55 "context"
66 "fmt"
7+ "regexp"
78 "strings"
89 "text/tabwriter"
910 "time"
@@ -12,32 +13,47 @@ import (
1213 o "github.com/onsi/gomega"
1314 "github.com/stretchr/objx"
1415
16+ v1 "github.com/openshift/api/config/v1"
17+ configclient "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
18+ machineclient "github.com/openshift/client-go/machine/clientset/versioned"
19+ exutil "github.com/openshift/origin/test/extended/util"
1520 "k8s.io/apimachinery/pkg/api/errors"
1621 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1722 "k8s.io/apimachinery/pkg/runtime/schema"
1823 "k8s.io/apimachinery/pkg/util/sets"
1924 "k8s.io/apimachinery/pkg/util/wait"
2025 "k8s.io/client-go/dynamic"
26+ "k8s.io/client-go/kubernetes"
2127 coreclient "k8s.io/client-go/kubernetes/typed/core/v1"
28+ "k8s.io/client-go/rest"
2229 e2e "k8s.io/kubernetes/test/e2e/framework"
2330 e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"
2431)
2532
2633const (
27- operatorWait = 1 * time .Minute
34+ operatorWait = 1 * time .Minute
35+ masterMachineLabelSelector = "machine.openshift.io/cluster-api-machine-role=master"
2836)
2937
3038var _ = g .Describe ("[sig-cluster-lifecycle][Feature:Machines] Managed cluster should" , func () {
3139 defer g .GinkgoRecover ()
40+ oc := exutil .NewCLIWithoutNamespace ("control-plane-machines" ).AsAdmin ()
3241
33- g .It ("have machine resources [apigroup:machine.openshift.io]" , func () {
34- cfg , err := e2e .LoadConfig ()
42+ var cfg * rest.Config
43+ var c * kubernetes.Clientset
44+ var dc * dynamic.DynamicClient
45+ var err error
46+
47+ g .BeforeEach (func () {
48+ cfg , err = e2e .LoadConfig ()
3549 o .Expect (err ).NotTo (o .HaveOccurred ())
36- c , err : = e2e .LoadClientset ()
50+ c , err = e2e .LoadClientset ()
3751 o .Expect (err ).NotTo (o .HaveOccurred ())
38- dc , err : = dynamic .NewForConfig (cfg )
52+ dc , err = dynamic .NewForConfig (cfg )
3953 o .Expect (err ).NotTo (o .HaveOccurred ())
54+ })
4055
56+ g .It ("have machine resources [apigroup:machine.openshift.io]" , func () {
4157 g .By ("checking for the openshift machine api operator" )
4258 // TODO: skip if platform != aws
4359 skipUnlessMachineAPIOperator (dc , c .CoreV1 ().Namespaces ())
@@ -100,6 +116,91 @@ var _ = g.Describe("[sig-cluster-lifecycle][Feature:Machines] Managed cluster sh
100116 e2e .Failf ("Machine resources missing for nodes: %s" , strings .Join (nodeNames .List (), ", " ))
101117 }
102118 })
119+
120+ g .It ("[sig-scheduling][Early] control plane machine set operator should not cause an early rollout" , func () {
121+ machineClientSet , err := machineclient .NewForConfig (oc .KubeFramework ().ClientConfig ())
122+ o .Expect (err ).ToNot (o .HaveOccurred ())
123+
124+ pattern := `^([a-zA-Z0-9]+-)+master-\d+$`
125+
126+ g .By ("checking for the openshift machine api operator" )
127+ skipUnlessMachineAPIOperator (dc , c .CoreV1 ().Namespaces ())
128+
129+ g .By ("ensuring every node is linked to a machine api resource" )
130+ allControlPlaneMachines , err := machineClientSet .MachineV1beta1 ().Machines ("openshift-machine-api" ).List (context .Background (), metav1.ListOptions {
131+ LabelSelector : masterMachineLabelSelector ,
132+ })
133+ o .Expect (err ).NotTo (o .HaveOccurred ())
134+
135+ regex , err := regexp .Compile (pattern )
136+ o .Expect (err ).NotTo (o .HaveOccurred ())
137+
138+ for _ , m := range allControlPlaneMachines .Items {
139+ matched := regex .MatchString (m .Name )
140+ o .Expect (matched ).To (o .BeTrue (), fmt .Sprintf ("unexpected name of a control machine occured during early stages: %s" , m .Name ))
141+ }
142+ })
143+
144+ g .It ("[sig-scheduling][Early] control plane machine set operator should not have any events" , func () {
145+ ctx := context .Background ()
146+
147+ nodeClient := oc .KubeClient ().CoreV1 ().Nodes ()
148+ nodeList , err := nodeClient .List (ctx , metav1.ListOptions {})
149+ o .Expect (err ).ToNot (o .HaveOccurred ())
150+
151+ // We want to skip this test on single-node clusters
152+ // as the control plane machine set does not get generated.
153+ // No other topology should match this condition.
154+ if len (nodeList .Items ) == 1 {
155+ _ , isWorker := nodeList .Items [0 ].Labels ["node-role.kubernetes.io/worker" ]
156+ _ , isControlPlane := nodeList .Items [0 ].Labels ["node-role.kubernetes.io/control-plane" ]
157+
158+ if isWorker && isControlPlane {
159+ g .Skip ("Skipping test due to a cluster being a single node cluster" )
160+ }
161+ }
162+
163+ configClient , err := configclient .NewForConfig (oc .KubeFramework ().ClientConfig ())
164+ o .Expect (err ).ToNot (o .HaveOccurred ())
165+
166+ infrastructure , err := configClient .Infrastructures ().Get (ctx , "cluster" , metav1.GetOptions {})
167+ o .Expect (err ).ToNot (o .HaveOccurred ())
168+
169+ platform := infrastructure .Status .PlatformStatus .Type
170+
171+ switch platform {
172+ case v1 .AWSPlatformType ,
173+ v1 .AzurePlatformType ,
174+ v1 .GCPPlatformType ,
175+ v1 .NutanixPlatformType ,
176+ v1 .OpenStackPlatformType :
177+ // Continue with the test
178+ default :
179+ g .Skip (fmt .Sprintf ("Skipping test on platform: %s" , platform ))
180+ }
181+
182+ machineClientSet , err := machineclient .NewForConfig (oc .KubeFramework ().ClientConfig ())
183+ o .Expect (err ).ToNot (o .HaveOccurred ())
184+
185+ g .By ("checking for the openshift machine api operator" )
186+ skipUnlessMachineAPIOperator (dc , c .CoreV1 ().Namespaces ())
187+
188+ g .By ("getting the control plane machine set" )
189+ cpmsClient := machineClientSet .MachineV1 ().ControlPlaneMachineSets ("openshift-machine-api" )
190+ cpms , err := cpmsClient .Get (ctx , "cluster" , metav1.GetOptions {})
191+ o .Expect (err ).ToNot (o .HaveOccurred ())
192+
193+ g .By ("getting the events from the control plane machine set" )
194+ eventsClient := oc .KubeClient ().CoreV1 ().Events ("openshift-machine-api" )
195+ fieldSelector := fmt .Sprintf ("involvedObject.kind=%s,involvedObject.name=%s" , cpms .Kind , cpms .Name )
196+ cpmsEvents , err := eventsClient .List (ctx , metav1.ListOptions {
197+ FieldSelector : fieldSelector ,
198+ })
199+ o .Expect (err ).ToNot (o .HaveOccurred ())
200+
201+ g .By ("the control plane machine set should not have any events" )
202+ o .Expect (cpmsEvents .Items ).Should (o .BeEmpty ())
203+ })
103204})
104205
105206// skipUnlessMachineAPI is used to deterine if the Machine API is installed and running in a cluster.
0 commit comments