sigs.k8s.io/cluster-api@v1.7.1/bootstrap/kubeadm/types/utils_test.go (about)

     1  /*
     2  Copyright 2021 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 utils
    18  
    19  import (
    20  	"testing"
    21  
    22  	"github.com/blang/semver/v4"
    23  	"github.com/google/go-cmp/cmp"
    24  	. "github.com/onsi/gomega"
    25  	"k8s.io/apimachinery/pkg/runtime/schema"
    26  
    27  	bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
    28  	"sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/upstreamv1beta2"
    29  	"sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/upstreamv1beta3"
    30  )
    31  
    32  func TestKubeVersionToKubeadmAPIGroupVersion(t *testing.T) {
    33  	type args struct {
    34  		version semver.Version
    35  	}
    36  	tests := []struct {
    37  		name    string
    38  		args    args
    39  		want    schema.GroupVersion
    40  		wantErr bool
    41  	}{
    42  		{
    43  			name: "fails when kubernetes version is too old",
    44  			args: args{
    45  				version: semver.MustParse("1.12.0"),
    46  			},
    47  			want:    schema.GroupVersion{},
    48  			wantErr: true,
    49  		},
    50  		{
    51  			name: "fails with kubernetes version for kubeadm API v1beta1",
    52  			args: args{
    53  				version: semver.MustParse("1.14.99"),
    54  			},
    55  			wantErr: true,
    56  		},
    57  		{
    58  			name: "pass with minimum kubernetes alpha version for kubeadm API v1beta2",
    59  			args: args{
    60  				version: semver.MustParse("1.15.0-alpha.0.734+ba502ee555924a"),
    61  			},
    62  			want:    upstreamv1beta2.GroupVersion,
    63  			wantErr: false,
    64  		},
    65  		{
    66  			name: "pass with minimum kubernetes version for kubeadm API v1beta2",
    67  			args: args{
    68  				version: semver.MustParse("1.15.0"),
    69  			},
    70  			want:    upstreamv1beta2.GroupVersion,
    71  			wantErr: false,
    72  		},
    73  		{
    74  			name: "pass with kubernetes version for kubeadm API v1beta2",
    75  			args: args{
    76  				version: semver.MustParse("1.20.99"),
    77  			},
    78  			want:    upstreamv1beta2.GroupVersion,
    79  			wantErr: false,
    80  		},
    81  		{
    82  			name: "pass with minimum kubernetes alpha version for kubeadm API v1beta3",
    83  			args: args{
    84  				version: semver.MustParse("1.22.0-alpha.0.734+ba502ee555924a"),
    85  			},
    86  			want:    upstreamv1beta3.GroupVersion,
    87  			wantErr: false,
    88  		},
    89  		{
    90  			name: "pass with minimum kubernetes version for kubeadm API v1beta3",
    91  			args: args{
    92  				version: semver.MustParse("1.22.0"),
    93  			},
    94  			want:    upstreamv1beta3.GroupVersion,
    95  			wantErr: false,
    96  		},
    97  		{
    98  			name: "pass with kubernetes version for kubeadm API v1beta3",
    99  			args: args{
   100  				version: semver.MustParse("1.23.99"),
   101  			},
   102  			want:    upstreamv1beta3.GroupVersion,
   103  			wantErr: false,
   104  		},
   105  		{
   106  			name: "pass with future kubernetes version",
   107  			args: args{
   108  				version: semver.MustParse("99.99.99"),
   109  			},
   110  			want:    upstreamv1beta3.GroupVersion,
   111  			wantErr: false,
   112  		},
   113  	}
   114  	for _, tt := range tests {
   115  		t.Run(tt.name, func(t *testing.T) {
   116  			g := NewWithT(t)
   117  
   118  			got, err := KubeVersionToKubeadmAPIGroupVersion(tt.args.version)
   119  			if tt.wantErr {
   120  				g.Expect(err).To(HaveOccurred())
   121  				return
   122  			}
   123  			g.Expect(err).ToNot(HaveOccurred())
   124  			g.Expect(got).To(BeComparableTo(tt.want))
   125  		})
   126  	}
   127  }
   128  
   129  func TestMarshalClusterConfigurationForVersion(t *testing.T) {
   130  	type args struct {
   131  		capiObj *bootstrapv1.ClusterConfiguration
   132  		version semver.Version
   133  	}
   134  	tests := []struct {
   135  		name    string
   136  		args    args
   137  		want    string
   138  		wantErr bool
   139  	}{
   140  		{
   141  			name: "Generates a v1beta2 kubeadm configuration",
   142  			args: args{
   143  				capiObj: &bootstrapv1.ClusterConfiguration{},
   144  				version: semver.MustParse("1.15.0"),
   145  			},
   146  			want: "apiServer: {}\n" +
   147  				"apiVersion: kubeadm.k8s.io/v1beta2\n" + "" +
   148  				"controllerManager: {}\n" +
   149  				"dns: {}\n" +
   150  				"etcd: {}\n" +
   151  				"kind: ClusterConfiguration\n" +
   152  				"networking: {}\n" +
   153  				"scheduler: {}\n",
   154  			wantErr: false,
   155  		},
   156  		{
   157  			name: "Generates a v1beta3 kubeadm configuration",
   158  			args: args{
   159  				capiObj: &bootstrapv1.ClusterConfiguration{},
   160  				version: semver.MustParse("1.22.0"),
   161  			},
   162  			want: "apiServer: {}\n" +
   163  				"apiVersion: kubeadm.k8s.io/v1beta3\n" + "" +
   164  				"controllerManager: {}\n" +
   165  				"dns: {}\n" +
   166  				"etcd: {}\n" +
   167  				"kind: ClusterConfiguration\n" +
   168  				"networking: {}\n" +
   169  				"scheduler: {}\n",
   170  			wantErr: false,
   171  		},
   172  	}
   173  	for _, tt := range tests {
   174  		t.Run(tt.name, func(t *testing.T) {
   175  			g := NewWithT(t)
   176  
   177  			got, err := MarshalClusterConfigurationForVersion(tt.args.capiObj, tt.args.version)
   178  			if tt.wantErr {
   179  				g.Expect(err).To(HaveOccurred())
   180  				return
   181  			}
   182  			g.Expect(err).ToNot(HaveOccurred())
   183  			g.Expect(got).To(Equal(tt.want), cmp.Diff(tt.want, got))
   184  		})
   185  	}
   186  }
   187  
   188  func TestMarshalClusterStatusForVersion(t *testing.T) {
   189  	type args struct {
   190  		capiObj *bootstrapv1.ClusterStatus
   191  		version semver.Version
   192  	}
   193  	tests := []struct {
   194  		name    string
   195  		args    args
   196  		want    string
   197  		wantErr bool
   198  	}{
   199  		{
   200  			name: "Generates a v1beta2 kubeadm status",
   201  			args: args{
   202  				capiObj: &bootstrapv1.ClusterStatus{},
   203  				version: semver.MustParse("1.15.0"),
   204  			},
   205  			want: "apiEndpoints: null\n" +
   206  				"apiVersion: kubeadm.k8s.io/v1beta2\n" + "" +
   207  				"kind: ClusterStatus\n",
   208  			wantErr: false,
   209  		},
   210  		{
   211  			name: "Fails generating a v1beta3 kubeadm status",
   212  			args: args{
   213  				capiObj: &bootstrapv1.ClusterStatus{},
   214  				version: semver.MustParse("1.22.0"),
   215  			},
   216  			wantErr: true,
   217  		},
   218  	}
   219  	for _, tt := range tests {
   220  		t.Run(tt.name, func(t *testing.T) {
   221  			g := NewWithT(t)
   222  
   223  			got, err := MarshalClusterStatusForVersion(tt.args.capiObj, tt.args.version)
   224  			if tt.wantErr {
   225  				g.Expect(err).To(HaveOccurred())
   226  				return
   227  			}
   228  			g.Expect(err).ToNot(HaveOccurred())
   229  			g.Expect(got).To(Equal(tt.want), cmp.Diff(tt.want, got))
   230  		})
   231  	}
   232  }
   233  
   234  func TestMarshalInitConfigurationForVersion(t *testing.T) {
   235  	type args struct {
   236  		capiObj *bootstrapv1.InitConfiguration
   237  		version semver.Version
   238  	}
   239  	tests := []struct {
   240  		name    string
   241  		args    args
   242  		want    string
   243  		wantErr bool
   244  	}{
   245  		{
   246  			name: "Generates a v1beta2 kubeadm configuration",
   247  			args: args{
   248  				capiObj: &bootstrapv1.InitConfiguration{
   249  					NodeRegistration: bootstrapv1.NodeRegistrationOptions{
   250  						IgnorePreflightErrors: []string{"some-preflight-check"},
   251  					},
   252  				},
   253  				version: semver.MustParse("1.15.0"),
   254  			},
   255  			want: "apiVersion: kubeadm.k8s.io/v1beta2\n" +
   256  				"kind: InitConfiguration\n" +
   257  				"localAPIEndpoint: {}\n" +
   258  				"nodeRegistration:\n" +
   259  				"  ignorePreflightErrors:\n" +
   260  				"  - some-preflight-check\n",
   261  			wantErr: false,
   262  		},
   263  		{
   264  			name: "Generates a v1beta3 kubeadm configuration",
   265  			args: args{
   266  				capiObj: &bootstrapv1.InitConfiguration{
   267  					NodeRegistration: bootstrapv1.NodeRegistrationOptions{
   268  						IgnorePreflightErrors: []string{"some-preflight-check"},
   269  					},
   270  				},
   271  				version: semver.MustParse("1.22.0"),
   272  			},
   273  			want: "apiVersion: kubeadm.k8s.io/v1beta3\n" +
   274  				"kind: InitConfiguration\n" +
   275  				"localAPIEndpoint: {}\n" +
   276  				"nodeRegistration:\n" +
   277  				"  ignorePreflightErrors:\n" +
   278  				"  - some-preflight-check\n" +
   279  				"  taints: null\n",
   280  			wantErr: false,
   281  		},
   282  	}
   283  	for _, tt := range tests {
   284  		t.Run(tt.name, func(t *testing.T) {
   285  			g := NewWithT(t)
   286  
   287  			got, err := MarshalInitConfigurationForVersion(tt.args.capiObj, tt.args.version)
   288  			if tt.wantErr {
   289  				g.Expect(err).To(HaveOccurred())
   290  				return
   291  			}
   292  			g.Expect(err).ToNot(HaveOccurred())
   293  			g.Expect(got).To(Equal(tt.want), cmp.Diff(tt.want, got))
   294  		})
   295  	}
   296  }
   297  
   298  func TestMarshalJoinConfigurationForVersion(t *testing.T) {
   299  	type args struct {
   300  		capiObj *bootstrapv1.JoinConfiguration
   301  		version semver.Version
   302  	}
   303  	tests := []struct {
   304  		name    string
   305  		args    args
   306  		want    string
   307  		wantErr bool
   308  	}{
   309  		{
   310  			name: "Generates a v1beta2 kubeadm configuration",
   311  			args: args{
   312  				capiObj: &bootstrapv1.JoinConfiguration{
   313  					NodeRegistration: bootstrapv1.NodeRegistrationOptions{
   314  						IgnorePreflightErrors: []string{"some-preflight-check"},
   315  					},
   316  				},
   317  				version: semver.MustParse("1.15.0"),
   318  			},
   319  			want: "apiVersion: kubeadm.k8s.io/v1beta2\n" + "" +
   320  				"discovery: {}\n" +
   321  				"kind: JoinConfiguration\n" +
   322  				"nodeRegistration:\n" +
   323  				"  ignorePreflightErrors:\n" +
   324  				"  - some-preflight-check\n",
   325  			wantErr: false,
   326  		},
   327  		{
   328  			name: "Generates a v1beta3 kubeadm configuration",
   329  			args: args{
   330  				capiObj: &bootstrapv1.JoinConfiguration{
   331  					NodeRegistration: bootstrapv1.NodeRegistrationOptions{
   332  						IgnorePreflightErrors: []string{"some-preflight-check"},
   333  					},
   334  				},
   335  				version: semver.MustParse("1.22.0"),
   336  			},
   337  			want: "apiVersion: kubeadm.k8s.io/v1beta3\n" + "" +
   338  				"discovery: {}\n" +
   339  				"kind: JoinConfiguration\n" +
   340  				"nodeRegistration:\n" +
   341  				"  ignorePreflightErrors:\n" +
   342  				"  - some-preflight-check\n" +
   343  				"  taints: null\n",
   344  			wantErr: false,
   345  		},
   346  	}
   347  	for _, tt := range tests {
   348  		t.Run(tt.name, func(t *testing.T) {
   349  			g := NewWithT(t)
   350  
   351  			got, err := MarshalJoinConfigurationForVersion(tt.args.capiObj, tt.args.version)
   352  			if tt.wantErr {
   353  				g.Expect(err).To(HaveOccurred())
   354  				return
   355  			}
   356  			g.Expect(err).ToNot(HaveOccurred())
   357  			g.Expect(got).To(Equal(tt.want), cmp.Diff(tt.want, got))
   358  		})
   359  	}
   360  }
   361  
   362  func TestUnmarshalClusterConfiguration(t *testing.T) {
   363  	type args struct {
   364  		yaml string
   365  	}
   366  	tests := []struct {
   367  		name    string
   368  		args    args
   369  		want    *bootstrapv1.ClusterConfiguration
   370  		wantErr bool
   371  	}{
   372  		{
   373  			name: "Parses a v1beta2 kubeadm configuration",
   374  			args: args{
   375  				yaml: "apiServer: {}\n" +
   376  					"apiVersion: kubeadm.k8s.io/v1beta2\n" + "" +
   377  					"controllerManager: {}\n" +
   378  					"dns: {}\n" +
   379  					"etcd: {}\n" +
   380  					"kind: ClusterConfiguration\n" +
   381  					"networking: {}\n" +
   382  					"scheduler: {}\n",
   383  			},
   384  			want:    &bootstrapv1.ClusterConfiguration{},
   385  			wantErr: false,
   386  		},
   387  		{
   388  			name: "Parses a v1beta3 kubeadm configuration",
   389  			args: args{
   390  				yaml: "apiServer: {}\n" +
   391  					"apiVersion: kubeadm.k8s.io/v1beta3\n" + "" +
   392  					"controllerManager: {}\n" +
   393  					"dns: {}\n" +
   394  					"etcd: {}\n" +
   395  					"kind: ClusterConfiguration\n" +
   396  					"networking: {}\n" +
   397  					"scheduler: {}\n",
   398  			},
   399  			want:    &bootstrapv1.ClusterConfiguration{},
   400  			wantErr: false,
   401  		},
   402  	}
   403  	for _, tt := range tests {
   404  		t.Run(tt.name, func(t *testing.T) {
   405  			g := NewWithT(t)
   406  
   407  			got, err := UnmarshalClusterConfiguration(tt.args.yaml)
   408  			if tt.wantErr {
   409  				g.Expect(err).To(HaveOccurred())
   410  				return
   411  			}
   412  			g.Expect(err).ToNot(HaveOccurred())
   413  			g.Expect(got).To(BeComparableTo(tt.want), cmp.Diff(tt.want, got))
   414  		})
   415  	}
   416  }
   417  
   418  func TestUnmarshalClusterStatus(t *testing.T) {
   419  	type args struct {
   420  		yaml string
   421  	}
   422  	tests := []struct {
   423  		name    string
   424  		args    args
   425  		want    *bootstrapv1.ClusterStatus
   426  		wantErr bool
   427  	}{
   428  		{
   429  			name: "Parses a v1beta2 kubeadm configuration",
   430  			args: args{
   431  				yaml: "apiEndpoints: null\n" +
   432  					"apiVersion: kubeadm.k8s.io/v1beta2\n" + "" +
   433  					"kind: ClusterStatus\n",
   434  			},
   435  			want:    &bootstrapv1.ClusterStatus{},
   436  			wantErr: false,
   437  		},
   438  		{
   439  			name: "Fails parsing a v1beta3 kubeadm configuration",
   440  			args: args{
   441  				yaml: "apiEndpoints: null\n" +
   442  					"apiVersion: kubeadm.k8s.io/v1beta3\n" + "" +
   443  					"kind: ClusterStatus\n",
   444  			},
   445  			wantErr: true,
   446  		},
   447  	}
   448  	for _, tt := range tests {
   449  		t.Run(tt.name, func(t *testing.T) {
   450  			g := NewWithT(t)
   451  
   452  			got, err := UnmarshalClusterStatus(tt.args.yaml)
   453  			if tt.wantErr {
   454  				g.Expect(err).To(HaveOccurred())
   455  				return
   456  			}
   457  			g.Expect(err).ToNot(HaveOccurred())
   458  			g.Expect(got).To(BeComparableTo(tt.want), cmp.Diff(tt.want, got))
   459  		})
   460  	}
   461  }
   462  
   463  func TestUnmarshalInitConfiguration(t *testing.T) {
   464  	type args struct {
   465  		yaml string
   466  	}
   467  	tests := []struct {
   468  		name    string
   469  		args    args
   470  		want    *bootstrapv1.InitConfiguration
   471  		wantErr bool
   472  	}{
   473  		{
   474  			name: "Parses a v1beta2 kubeadm configuration",
   475  			args: args{
   476  				yaml: "apiVersion: kubeadm.k8s.io/v1beta2\n" + "" +
   477  					"kind: InitConfiguration\n" +
   478  					"localAPIEndpoint: {}\n" +
   479  					"nodeRegistration: {}\n",
   480  			},
   481  			want:    &bootstrapv1.InitConfiguration{},
   482  			wantErr: false,
   483  		},
   484  		{
   485  			name: "Parses a v1beta3 kubeadm configuration",
   486  			args: args{
   487  				yaml: "apiVersion: kubeadm.k8s.io/v1beta3\n" + "" +
   488  					"kind: InitConfiguration\n" +
   489  					"localAPIEndpoint: {}\n" +
   490  					"nodeRegistration: {}\n",
   491  			},
   492  			want:    &bootstrapv1.InitConfiguration{},
   493  			wantErr: false,
   494  		},
   495  	}
   496  	for _, tt := range tests {
   497  		t.Run(tt.name, func(t *testing.T) {
   498  			g := NewWithT(t)
   499  
   500  			got, err := UnmarshalInitConfiguration(tt.args.yaml)
   501  			if tt.wantErr {
   502  				g.Expect(err).To(HaveOccurred())
   503  				return
   504  			}
   505  			g.Expect(err).ToNot(HaveOccurred())
   506  			g.Expect(got).To(BeComparableTo(tt.want), cmp.Diff(tt.want, got))
   507  		})
   508  	}
   509  }
   510  
   511  func TestUnmarshalJoinConfiguration(t *testing.T) {
   512  	type args struct {
   513  		yaml string
   514  	}
   515  	tests := []struct {
   516  		name    string
   517  		args    args
   518  		want    *bootstrapv1.JoinConfiguration
   519  		wantErr bool
   520  	}{
   521  		{
   522  			name: "Parses a v1beta2 kubeadm configuration",
   523  			args: args{
   524  				yaml: "apiVersion: kubeadm.k8s.io/v1beta2\n" + "" +
   525  					"caCertPath: \"\"\n" +
   526  					"discovery: {}\n" +
   527  					"kind: JoinConfiguration\n",
   528  			},
   529  			want:    &bootstrapv1.JoinConfiguration{},
   530  			wantErr: false,
   531  		},
   532  		{
   533  			name: "Parses a v1beta3 kubeadm configuration",
   534  			args: args{
   535  				yaml: "apiVersion: kubeadm.k8s.io/v1beta3\n" + "" +
   536  					"caCertPath: \"\"\n" +
   537  					"discovery: {}\n" +
   538  					"kind: JoinConfiguration\n",
   539  			},
   540  			want:    &bootstrapv1.JoinConfiguration{},
   541  			wantErr: false,
   542  		},
   543  	}
   544  	for _, tt := range tests {
   545  		t.Run(tt.name, func(t *testing.T) {
   546  			g := NewWithT(t)
   547  
   548  			got, err := UnmarshalJoinConfiguration(tt.args.yaml)
   549  			if tt.wantErr {
   550  				g.Expect(err).To(HaveOccurred())
   551  				return
   552  			}
   553  			g.Expect(err).ToNot(HaveOccurred())
   554  			g.Expect(got).To(BeComparableTo(tt.want), cmp.Diff(tt.want, got))
   555  		})
   556  	}
   557  }