sigs.k8s.io/cluster-api@v1.7.1/cmd/clusterctl/client/alpha/rollout_rollbacker_test.go (about)

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package alpha
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  
    23  	. "github.com/onsi/gomega"
    24  	corev1 "k8s.io/api/core/v1"
    25  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    26  	"k8s.io/utils/ptr"
    27  	"sigs.k8s.io/controller-runtime/pkg/client"
    28  
    29  	clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
    30  	"sigs.k8s.io/cluster-api/cmd/clusterctl/internal/test"
    31  )
    32  
    33  func Test_ObjectRollbacker(t *testing.T) {
    34  	labels := map[string]string{
    35  		clusterv1.ClusterNameLabel:           "test",
    36  		clusterv1.MachineDeploymentNameLabel: "test-md-0",
    37  	}
    38  	currentVersion := "v1.19.3"
    39  	rollbackVersion := "v1.19.1"
    40  	deployment := &clusterv1.MachineDeployment{
    41  		TypeMeta: metav1.TypeMeta{
    42  			Kind: "MachineDeployment",
    43  		},
    44  		ObjectMeta: metav1.ObjectMeta{
    45  			Name:      "test-md-0",
    46  			Namespace: "default",
    47  			Labels: map[string]string{
    48  				clusterv1.ClusterNameLabel: "test",
    49  			},
    50  			Annotations: map[string]string{
    51  				clusterv1.RevisionAnnotation: "2",
    52  			},
    53  		},
    54  		Spec: clusterv1.MachineDeploymentSpec{
    55  			ClusterName: "test",
    56  			Selector: metav1.LabelSelector{
    57  				MatchLabels: map[string]string{
    58  					clusterv1.ClusterNameLabel: "test",
    59  				},
    60  			},
    61  			Template: clusterv1.MachineTemplateSpec{
    62  				ObjectMeta: clusterv1.ObjectMeta{
    63  					Labels: labels,
    64  				},
    65  				Spec: clusterv1.MachineSpec{
    66  					ClusterName: "test",
    67  					Version:     &currentVersion,
    68  					InfrastructureRef: corev1.ObjectReference{
    69  						APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1",
    70  						Kind:       "InfrastructureMachineTemplate",
    71  						Name:       "md-template",
    72  					},
    73  					Bootstrap: clusterv1.Bootstrap{
    74  						DataSecretName: ptr.To("data-secret-name"),
    75  					},
    76  				},
    77  			},
    78  		},
    79  	}
    80  	type fields struct {
    81  		objs       []client.Object
    82  		ref        corev1.ObjectReference
    83  		toRevision int64
    84  	}
    85  	tests := []struct {
    86  		name                   string
    87  		fields                 fields
    88  		wantErr                bool
    89  		wantVersion            string
    90  		wantInfraTemplate      string
    91  		wantBootsrapSecretName string
    92  	}{
    93  		{
    94  			name: "machinedeployment should rollback to revision=1",
    95  			fields: fields{
    96  				objs: []client.Object{
    97  					deployment,
    98  					&clusterv1.MachineSet{
    99  						TypeMeta: metav1.TypeMeta{
   100  							Kind: "MachineSet",
   101  						},
   102  						ObjectMeta: metav1.ObjectMeta{
   103  							Name:      "ms-rev-2",
   104  							Namespace: "default",
   105  							OwnerReferences: []metav1.OwnerReference{
   106  								*metav1.NewControllerRef(deployment, clusterv1.GroupVersion.WithKind("MachineDeployment")),
   107  							},
   108  							Labels: map[string]string{
   109  								clusterv1.ClusterNameLabel: "test",
   110  							},
   111  							Annotations: map[string]string{
   112  								clusterv1.RevisionAnnotation: "2",
   113  							},
   114  						},
   115  					},
   116  					&clusterv1.MachineSet{
   117  						TypeMeta: metav1.TypeMeta{
   118  							Kind: "MachineSet",
   119  						},
   120  						ObjectMeta: metav1.ObjectMeta{
   121  							Namespace: "default",
   122  							Name:      "ms-rev-1",
   123  							OwnerReferences: []metav1.OwnerReference{
   124  								*metav1.NewControllerRef(deployment, clusterv1.GroupVersion.WithKind("MachineDeployment")),
   125  							},
   126  							Labels: map[string]string{
   127  								clusterv1.ClusterNameLabel: "test",
   128  							},
   129  							Annotations: map[string]string{
   130  								clusterv1.RevisionAnnotation: "999",
   131  							},
   132  						},
   133  						Spec: clusterv1.MachineSetSpec{
   134  							ClusterName: "test",
   135  							Selector: metav1.LabelSelector{
   136  								MatchLabels: map[string]string{
   137  									clusterv1.ClusterNameLabel: "test",
   138  								},
   139  							},
   140  							Template: clusterv1.MachineTemplateSpec{
   141  								ObjectMeta: clusterv1.ObjectMeta{
   142  									Labels: labels,
   143  								},
   144  								Spec: clusterv1.MachineSpec{
   145  									ClusterName: "test",
   146  									Version:     &rollbackVersion,
   147  									InfrastructureRef: corev1.ObjectReference{
   148  										APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1",
   149  										Kind:       "InfrastructureMachineTemplate",
   150  										Name:       "md-template-rollback",
   151  									},
   152  									Bootstrap: clusterv1.Bootstrap{
   153  										DataSecretName: ptr.To("data-secret-name-rollback"),
   154  									},
   155  								},
   156  							},
   157  						},
   158  					},
   159  				},
   160  				ref: corev1.ObjectReference{
   161  					Kind:      MachineDeployment,
   162  					Name:      "test-md-0",
   163  					Namespace: "default",
   164  				},
   165  				toRevision: int64(999),
   166  			},
   167  			wantErr:                false,
   168  			wantVersion:            rollbackVersion,
   169  			wantInfraTemplate:      "md-template-rollback",
   170  			wantBootsrapSecretName: "data-secret-name-rollback",
   171  		},
   172  		{
   173  			name: "machinedeployment should not rollback because there is no previous revision",
   174  			fields: fields{
   175  				objs: []client.Object{
   176  					deployment,
   177  					&clusterv1.MachineSet{
   178  						TypeMeta: metav1.TypeMeta{
   179  							Kind: "MachineSet",
   180  						},
   181  						ObjectMeta: metav1.ObjectMeta{
   182  							Name:      "ms-rev-2",
   183  							Namespace: "default",
   184  							OwnerReferences: []metav1.OwnerReference{
   185  								*metav1.NewControllerRef(deployment, clusterv1.GroupVersion.WithKind("MachineDeployment")),
   186  							},
   187  							Labels: map[string]string{
   188  								clusterv1.ClusterNameLabel: "test",
   189  							},
   190  							Annotations: map[string]string{
   191  								clusterv1.RevisionAnnotation: "2",
   192  							},
   193  						},
   194  					},
   195  				},
   196  				ref: corev1.ObjectReference{
   197  					Kind:      MachineDeployment,
   198  					Name:      "test-md-0",
   199  					Namespace: "default",
   200  				},
   201  				toRevision: int64(0),
   202  			},
   203  			wantErr: true,
   204  		},
   205  		{
   206  			name: "machinedeployment should not rollback because the specified version does not exist",
   207  			fields: fields{
   208  				objs: []client.Object{
   209  					deployment,
   210  					&clusterv1.MachineSet{
   211  						TypeMeta: metav1.TypeMeta{
   212  							Kind: "MachineSet",
   213  						},
   214  						ObjectMeta: metav1.ObjectMeta{
   215  							Name:      "ms-rev-2",
   216  							Namespace: "default",
   217  							OwnerReferences: []metav1.OwnerReference{
   218  								*metav1.NewControllerRef(deployment, clusterv1.GroupVersion.WithKind("MachineDeployment")),
   219  							},
   220  							Labels: map[string]string{
   221  								clusterv1.ClusterNameLabel: "test",
   222  							},
   223  							Annotations: map[string]string{
   224  								clusterv1.RevisionAnnotation: "2",
   225  							},
   226  						},
   227  					},
   228  				},
   229  				ref: corev1.ObjectReference{
   230  					Kind:      MachineDeployment,
   231  					Name:      "test-md-0",
   232  					Namespace: "default",
   233  				},
   234  				toRevision: int64(999),
   235  			},
   236  			wantErr: true,
   237  		},
   238  	}
   239  	for _, tt := range tests {
   240  		t.Run(tt.name, func(t *testing.T) {
   241  			g := NewWithT(t)
   242  			r := newRolloutClient()
   243  			proxy := test.NewFakeProxy().WithObjs(tt.fields.objs...)
   244  			err := r.ObjectRollbacker(context.Background(), proxy, tt.fields.ref, tt.fields.toRevision)
   245  			if tt.wantErr {
   246  				g.Expect(err).To(HaveOccurred())
   247  				return
   248  			}
   249  			g.Expect(err).ToNot(HaveOccurred())
   250  			cl, err := proxy.NewClient(context.Background())
   251  			g.Expect(err).ToNot(HaveOccurred())
   252  			key := client.ObjectKeyFromObject(deployment)
   253  			md := &clusterv1.MachineDeployment{}
   254  			err = cl.Get(context.TODO(), key, md)
   255  			g.Expect(err).ToNot(HaveOccurred())
   256  			g.Expect(*md.Spec.Template.Spec.Version).To(Equal(tt.wantVersion))
   257  			g.Expect(md.Spec.Template.Spec.InfrastructureRef.Name).To(Equal(tt.wantInfraTemplate))
   258  			g.Expect(*md.Spec.Template.Spec.Bootstrap.DataSecretName).To(Equal(tt.wantBootsrapSecretName))
   259  		})
   260  	}
   261  }