Skip to content

Commit 2ae3bea

Browse files
committed
auto migration cases
1 parent 1e2ffde commit 2ae3bea

File tree

6 files changed

+946
-1
lines changed

6 files changed

+946
-1
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ unit:
4444

4545
.PHONY: e2e
4646
e2e:
47-
./hack/test.sh "./e2e/..." 30m
47+
./hack/test.sh "./e2e/..." 60m
4848

4949
# Run against the configured Kubernetes cluster in ~/.kube/config
5050
run:

e2e/framework/machine.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package framework
22

33
import (
4+
"context"
45
"fmt"
56

67
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -54,3 +55,15 @@ func FilterRunningMachines(machines []*clusterv1.Machine) []*clusterv1.Machine {
5455

5556
return result
5657
}
58+
59+
// GetMachine get a machine by its name from the cluster API namespace.
60+
func GetMachine(cl client.Client, name string) (*clusterv1.Machine, error) {
61+
machine := &clusterv1.Machine{}
62+
key := client.ObjectKey{Namespace: CAPINamespace, Name: name}
63+
64+
if err := cl.Get(context.Background(), key, machine); err != nil {
65+
return nil, fmt.Errorf("error querying api for machine object: %w", err)
66+
}
67+
68+
return machine, nil
69+
}

e2e/framework/machineset.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
11
package framework
22

33
import (
4+
"context"
45
"fmt"
6+
"time"
57

68
. "github.com/onsi/ginkgo/v2"
79
. "github.com/onsi/gomega"
810
corev1 "k8s.io/api/core/v1"
911
apierrors "k8s.io/apimachinery/pkg/api/errors"
1012
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13+
"k8s.io/apimachinery/pkg/runtime/schema"
14+
"k8s.io/apimachinery/pkg/util/wait"
15+
"k8s.io/client-go/discovery"
16+
"k8s.io/client-go/dynamic"
17+
"k8s.io/client-go/rest"
18+
"k8s.io/client-go/scale"
19+
"k8s.io/klog"
1120
"k8s.io/utils/pointer"
1221
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
1322
"sigs.k8s.io/controller-runtime/pkg/client"
23+
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
24+
"sigs.k8s.io/controller-runtime/pkg/client/config"
1425
)
1526

1627
type machineSetParams struct {
@@ -188,3 +199,106 @@ func GetMachinesFromMachineSet(cl client.Client, machineSet *clusterv1.MachineSe
188199
}
189200
return machinesForSet, nil
190201
}
202+
203+
// GetLatestMachineFromMachineSet returns the new created machine by a given machineSet.
204+
func GetLatestMachineFromMachineSet(cl client.Client, machineSet *clusterv1.MachineSet) (*clusterv1.Machine, error) {
205+
machines, err := GetMachinesFromMachineSet(cl, machineSet)
206+
if err != nil {
207+
return nil, fmt.Errorf("error getting machines: %w", err)
208+
}
209+
210+
var machine *clusterv1.Machine
211+
212+
newest := time.Date(2020, 0, 1, 12, 0, 0, 0, time.UTC)
213+
214+
for key := range machines {
215+
time := machines[key].CreationTimestamp.Time
216+
if time.After(newest) {
217+
newest = time
218+
machine = machines[key]
219+
}
220+
}
221+
222+
return machine, nil
223+
}
224+
225+
// DeleteMachines deletes the specified machines and returns an error on failure.
226+
func DeleteMachines(cl client.Client, machines ...*clusterv1.Machine) error {
227+
return wait.PollUntilContextTimeout(ctx, RetryShort, time.Minute, true, func(ctx context.Context) (bool, error) {
228+
for _, machine := range machines {
229+
if err := cl.Delete(ctx, machine); err != nil {
230+
klog.Errorf("Error querying api for machine object %q: %v, retrying...", machine.Name, err)
231+
return false, err
232+
}
233+
}
234+
235+
return true, nil
236+
})
237+
}
238+
239+
// WaitForMachinesDeleted polls until the given Machines are not found.
240+
func WaitForMachinesDeleted(cl client.Client, machines ...*clusterv1.Machine) {
241+
Eventually(func() bool {
242+
for _, m := range machines {
243+
if err := cl.Get(context.Background(), client.ObjectKey{
244+
Name: m.GetName(),
245+
Namespace: m.GetNamespace(),
246+
}, &clusterv1.Machine{}); !apierrors.IsNotFound(err) {
247+
return false // Not deleted, or other error.
248+
}
249+
}
250+
251+
return true // Everything was deleted.
252+
}, WaitLong, RetryMedium).Should(BeTrue(), "error encountered while waiting for Machines to be deleted.")
253+
}
254+
255+
// ScaleMachineSet scales a machineSet with a given name to the given number of replicas.
256+
func ScaleMachineSet(name string, replicas int) error {
257+
scaleClient, err := getScaleClient()
258+
if err != nil {
259+
return fmt.Errorf("error calling getScaleClient %w", err)
260+
}
261+
262+
scale, err := scaleClient.Scales(CAPINamespace).Get(ctx, schema.GroupResource{Group: "cluster.x-k8s.io", Resource: "MachineSet"}, name, metav1.GetOptions{})
263+
if err != nil {
264+
return fmt.Errorf("error calling scaleClient.Scales get: %w", err)
265+
}
266+
267+
scaleUpdate := scale.DeepCopy()
268+
scaleUpdate.Spec.Replicas = int32(replicas)
269+
270+
_, err = scaleClient.Scales(CAPINamespace).Update(ctx, schema.GroupResource{Group: "cluster.x-k8s.io", Resource: "MachineSet"}, scaleUpdate, metav1.UpdateOptions{})
271+
if err != nil {
272+
return fmt.Errorf("error calling scaleClient.Scales update: %w", err)
273+
}
274+
275+
return nil
276+
}
277+
278+
// getScaleClient returns a ScalesGetter object to manipulate scale subresources.
279+
func getScaleClient() (scale.ScalesGetter, error) {
280+
cfg, err := config.GetConfig()
281+
if err != nil {
282+
return nil, fmt.Errorf("error getting config %w", err)
283+
}
284+
285+
httpClient, err := rest.HTTPClientFor(cfg)
286+
if err != nil {
287+
return nil, fmt.Errorf("error calling rest.HTTPClientFor %w", err)
288+
}
289+
290+
mapper, err := apiutil.NewDynamicRESTMapper(cfg, httpClient)
291+
if err != nil {
292+
return nil, fmt.Errorf("error calling NewDiscoveryRESTMapper %w", err)
293+
}
294+
295+
discovery := discovery.NewDiscoveryClientForConfigOrDie(cfg)
296+
scaleKindResolver := scale.NewDiscoveryScaleKindResolver(discovery)
297+
298+
scaleClient, err := scale.NewForConfig(cfg, mapper, dynamic.LegacyAPIPathResolverFunc, scaleKindResolver)
299+
if err != nil {
300+
return nil, fmt.Errorf("error calling building scale client %w", err)
301+
}
302+
303+
return scaleClient, nil
304+
}

e2e/framework/machinetemplate.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package framework
2+
3+
import (
4+
awsv1 "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
5+
azurev1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
6+
gcpv1 "sigs.k8s.io/cluster-api-provider-gcp/api/v1beta1"
7+
"sigs.k8s.io/controller-runtime/pkg/client"
8+
)
9+
10+
// GetAWSMachineTemplate gets awsMachineTemplate by its name from the default cluster API namespace.
11+
func GetAWSMachineTemplate(cl client.Client, name string) (*awsv1.AWSMachineTemplate, error) {
12+
var awsMachineTemplate = &awsv1.AWSMachineTemplate{}
13+
14+
key := client.ObjectKey{Namespace: CAPINamespace, Name: name}
15+
if err := cl.Get(ctx, key, awsMachineTemplate); err != nil {
16+
return nil, err
17+
}
18+
return awsMachineTemplate, nil
19+
}
20+
21+
// GetAzureMachineTemplate gets azureMachineTemplate by its name from the default cluster API namespace.
22+
func GetAzureMachineTemplate(cl client.Client, name string) (*azurev1.AzureMachineTemplate, error) {
23+
var azureMachineTemplate = &azurev1.AzureMachineTemplate{}
24+
25+
key := client.ObjectKey{Namespace: CAPINamespace, Name: name}
26+
if err := cl.Get(ctx, key, azureMachineTemplate); err != nil {
27+
return nil, err
28+
}
29+
return azureMachineTemplate, nil
30+
}
31+
32+
// GetGCPMachineTemplate gets gcpMachineTemplate by its name from the default cluster API namespace.
33+
func GetGCPMachineTemplate(cl client.Client, name string) (*gcpv1.GCPMachineTemplate, error) {
34+
var gcpMachineTemplate = &gcpv1.GCPMachineTemplate{}
35+
36+
key := client.ObjectKey{Namespace: CAPINamespace, Name: name}
37+
if err := cl.Get(ctx, key, gcpMachineTemplate); err != nil {
38+
return nil, err
39+
}
40+
return gcpMachineTemplate, nil
41+
}

e2e/framework/util.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package framework
22

33
import (
4+
"context"
45
"fmt"
56
"net/url"
67
"strconv"
78

89
configv1 "github.com/openshift/api/config/v1"
10+
"k8s.io/apimachinery/pkg/types"
911
"sigs.k8s.io/controller-runtime/pkg/client"
1012
)
1113

@@ -32,3 +34,21 @@ func GetControlPlaneHostAndPort(cl client.Client) (string, int32, error) {
3234

3335
return apiUrl.Hostname(), int32(port), nil
3436
}
37+
38+
// IsMachineAPIMigrationEnabled checks if the "MachineAPIMigration" feature is enabled via FeatureGate status
39+
func IsMachineAPIMigrationEnabled(ctx context.Context, cl client.Client) bool {
40+
featureGate := &configv1.FeatureGate{}
41+
if err := cl.Get(ctx, types.NamespacedName{Name: "cluster"}, featureGate); err != nil {
42+
return false
43+
}
44+
45+
for _, fg := range featureGate.Status.FeatureGates {
46+
for _, enabled := range fg.Enabled {
47+
if enabled.Name == "MachineAPIMigration" {
48+
return true
49+
}
50+
}
51+
}
52+
53+
return false
54+
}

0 commit comments

Comments
 (0)