sigs.k8s.io/cluster-api-provider-azure@v1.14.3/azure/converters/vmss_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 converters_test
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  
    23  	"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5"
    24  	"github.com/onsi/gomega"
    25  	"k8s.io/utils/ptr"
    26  	infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
    27  	"sigs.k8s.io/cluster-api-provider-azure/azure"
    28  	"sigs.k8s.io/cluster-api-provider-azure/azure/converters"
    29  )
    30  
    31  func Test_SDKToVMSS(t *testing.T) {
    32  	cases := []struct {
    33  		Name           string
    34  		SubjectFactory func(*gomega.GomegaWithT) (armcompute.VirtualMachineScaleSet, []armcompute.VirtualMachineScaleSetVM)
    35  		Expect         func(*gomega.GomegaWithT, azure.VMSS)
    36  	}{
    37  		{
    38  			Name: "ShouldPopulateWithData",
    39  			SubjectFactory: func(g *gomega.GomegaWithT) (armcompute.VirtualMachineScaleSet, []armcompute.VirtualMachineScaleSetVM) {
    40  				tags := map[string]*string{
    41  					"foo": ptr.To("bazz"),
    42  				}
    43  				zones := []string{"zone0", "zone1"}
    44  				return armcompute.VirtualMachineScaleSet{
    45  						SKU: &armcompute.SKU{
    46  							Name:     ptr.To("skuName"),
    47  							Tier:     ptr.To("skuTier"),
    48  							Capacity: ptr.To[int64](2),
    49  						},
    50  						Zones:    azure.PtrSlice(&zones),
    51  						ID:       ptr.To("vmssID"),
    52  						Name:     ptr.To("vmssName"),
    53  						Location: ptr.To("westus2"),
    54  						Tags:     tags,
    55  						Properties: &armcompute.VirtualMachineScaleSetProperties{
    56  							SinglePlacementGroup: ptr.To(false),
    57  							ProvisioningState:    ptr.To("Succeeded"),
    58  						},
    59  					},
    60  					[]armcompute.VirtualMachineScaleSetVM{
    61  						{
    62  							InstanceID: ptr.To("0"),
    63  							ID:         ptr.To("vm/0"),
    64  							Name:       ptr.To("vm0"),
    65  							Zones:      []*string{ptr.To("zone0")},
    66  							Properties: &armcompute.VirtualMachineScaleSetVMProperties{
    67  								ProvisioningState: ptr.To("Succeeded"),
    68  								OSProfile: &armcompute.OSProfile{
    69  									ComputerName: ptr.To("instance-000000"),
    70  								},
    71  							},
    72  						},
    73  						{
    74  							InstanceID: ptr.To("1"),
    75  							ID:         ptr.To("vm/1"),
    76  							Name:       ptr.To("vm1"),
    77  							Zones:      []*string{ptr.To("zone1")},
    78  							Properties: &armcompute.VirtualMachineScaleSetVMProperties{
    79  								ProvisioningState: ptr.To("Succeeded"),
    80  								OSProfile: &armcompute.OSProfile{
    81  									ComputerName: ptr.To("instance-000001"),
    82  								},
    83  							},
    84  						},
    85  					}
    86  			},
    87  			Expect: func(g *gomega.GomegaWithT, actual azure.VMSS) {
    88  				expected := azure.VMSS{
    89  					ID:       "vmssID",
    90  					Name:     "vmssName",
    91  					Sku:      "skuName",
    92  					Capacity: 2,
    93  					Zones:    []string{"zone0", "zone1"},
    94  					State:    "Succeeded",
    95  					Tags: map[string]string{
    96  						"foo": "bazz",
    97  					},
    98  					Instances: make([]azure.VMSSVM, 2),
    99  				}
   100  
   101  				for i := 0; i < 2; i++ {
   102  					expected.Instances[i] = azure.VMSSVM{
   103  						ID:               fmt.Sprintf("vm/%d", i),
   104  						InstanceID:       fmt.Sprintf("%d", i),
   105  						Name:             fmt.Sprintf("instance-00000%d", i),
   106  						AvailabilityZone: fmt.Sprintf("zone%d", i),
   107  						State:            "Succeeded",
   108  					}
   109  				}
   110  				g.Expect(actual).To(gomega.Equal(expected))
   111  			},
   112  		},
   113  	}
   114  
   115  	for _, c := range cases {
   116  		c := c
   117  		t.Run(c.Name, func(t *testing.T) {
   118  			t.Parallel()
   119  			g := gomega.NewGomegaWithT(t)
   120  			vmss, instances := c.SubjectFactory(g)
   121  			subject := converters.SDKToVMSS(vmss, instances)
   122  			c.Expect(g, subject)
   123  		})
   124  	}
   125  }
   126  
   127  func Test_SDKToVMSSVM(t *testing.T) {
   128  	cases := []struct {
   129  		Name        string
   130  		SDKInstance armcompute.VirtualMachineScaleSetVM
   131  		VMSSVM      *azure.VMSSVM
   132  	}{
   133  		{
   134  			Name: "minimal VM",
   135  			SDKInstance: armcompute.VirtualMachineScaleSetVM{
   136  				ID: ptr.To("vm/0"),
   137  			},
   138  			VMSSVM: &azure.VMSSVM{
   139  				ID: "vm/0",
   140  			},
   141  		},
   142  		{
   143  			Name: "VM with nil properties",
   144  			SDKInstance: armcompute.VirtualMachineScaleSetVM{
   145  				ID:         ptr.To("vm/0.5"),
   146  				Properties: nil,
   147  			},
   148  			VMSSVM: &azure.VMSSVM{
   149  				ID: "vm/0.5",
   150  			},
   151  		},
   152  		{
   153  			Name: "VM with state",
   154  			SDKInstance: armcompute.VirtualMachineScaleSetVM{
   155  				ID: ptr.To("/subscriptions/foo/resourceGroups/MY_RESOURCE_GROUP/providers/bar"),
   156  				Properties: &armcompute.VirtualMachineScaleSetVMProperties{
   157  					ProvisioningState: ptr.To(string("Succeeded")),
   158  					OSProfile:         &armcompute.OSProfile{ComputerName: ptr.To("instance-000000")},
   159  				},
   160  			},
   161  			VMSSVM: &azure.VMSSVM{
   162  				ID:    "/subscriptions/foo/resourceGroups/my_resource_group/providers/bar",
   163  				Name:  "instance-000000",
   164  				State: "Succeeded",
   165  			},
   166  		},
   167  		{
   168  			Name: "VM with storage",
   169  			SDKInstance: armcompute.VirtualMachineScaleSetVM{
   170  				ID: ptr.To("/subscriptions/foo/resourceGroups/MY_RESOURCE_GROUP/providers/bar"),
   171  				Properties: &armcompute.VirtualMachineScaleSetVMProperties{
   172  					OSProfile: &armcompute.OSProfile{ComputerName: ptr.To("instance-000001")},
   173  					StorageProfile: &armcompute.StorageProfile{
   174  						ImageReference: &armcompute.ImageReference{
   175  							ID: ptr.To("imageID"),
   176  						},
   177  					},
   178  				},
   179  			},
   180  			VMSSVM: &azure.VMSSVM{
   181  				ID:   "/subscriptions/foo/resourceGroups/my_resource_group/providers/bar",
   182  				Name: "instance-000001",
   183  				Image: infrav1.Image{
   184  					ID: ptr.To("imageID"),
   185  				},
   186  				State: "Creating",
   187  			},
   188  		},
   189  		{
   190  			Name: "VM with zones",
   191  			SDKInstance: armcompute.VirtualMachineScaleSetVM{
   192  				ID: ptr.To("/subscriptions/foo/resourceGroups/MY_RESOURCE_GROUP/providers/bar"),
   193  				Properties: &armcompute.VirtualMachineScaleSetVMProperties{
   194  					OSProfile: &armcompute.OSProfile{ComputerName: ptr.To("instance-000002")},
   195  				},
   196  				Zones: []*string{ptr.To("zone0"), ptr.To("zone1")},
   197  			},
   198  			VMSSVM: &azure.VMSSVM{
   199  				ID:               "/subscriptions/foo/resourceGroups/my_resource_group/providers/bar",
   200  				Name:             "instance-000002",
   201  				AvailabilityZone: "zone0",
   202  				State:            "Creating",
   203  			},
   204  		},
   205  	}
   206  
   207  	for _, c := range cases {
   208  		c := c
   209  		t.Run(c.Name, func(t *testing.T) {
   210  			t.Parallel()
   211  			g := gomega.NewGomegaWithT(t)
   212  			g.Expect(converters.SDKToVMSSVM(c.SDKInstance)).To(gomega.Equal(c.VMSSVM))
   213  		})
   214  	}
   215  }
   216  
   217  func Test_SDKImageToImage(t *testing.T) {
   218  	cases := []struct {
   219  		Name         string
   220  		SDKImageRef  *armcompute.ImageReference
   221  		IsThirdParty bool
   222  		Image        infrav1.Image
   223  	}{
   224  		{
   225  			Name: "id image",
   226  			SDKImageRef: &armcompute.ImageReference{
   227  				ID: ptr.To("imageID"),
   228  			},
   229  			IsThirdParty: false,
   230  			Image: infrav1.Image{
   231  				ID: ptr.To("imageID"),
   232  			},
   233  		},
   234  		{
   235  			Name: "marketplace image",
   236  			SDKImageRef: &armcompute.ImageReference{
   237  				Publisher: ptr.To("publisher"),
   238  				Offer:     ptr.To("offer"),
   239  				SKU:       ptr.To("sku"),
   240  				Version:   ptr.To("version"),
   241  			},
   242  			IsThirdParty: true,
   243  			Image: infrav1.Image{
   244  				Marketplace: &infrav1.AzureMarketplaceImage{
   245  					ImagePlan: infrav1.ImagePlan{
   246  						Publisher: "publisher",
   247  						Offer:     "offer",
   248  						SKU:       "sku",
   249  					},
   250  					Version:         "version",
   251  					ThirdPartyImage: true,
   252  				},
   253  			},
   254  		},
   255  		{
   256  			Name: "shared gallery image",
   257  			SDKImageRef: &armcompute.ImageReference{
   258  				SharedGalleryImageID: ptr.To("/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Compute/galleries/gallery/images/image/versions/version"),
   259  			},
   260  			Image: infrav1.Image{
   261  				SharedGallery: &infrav1.AzureSharedGalleryImage{
   262  					SubscriptionID: "subscription",
   263  					ResourceGroup:  "rg",
   264  					Gallery:        "gallery",
   265  					Name:           "image",
   266  					Version:        "version",
   267  				},
   268  			},
   269  		},
   270  		{
   271  			Name: "community gallery image",
   272  			SDKImageRef: &armcompute.ImageReference{
   273  				CommunityGalleryImageID: ptr.To("/CommunityGalleries/gallery/Images/image/Versions/version"),
   274  			},
   275  			Image: infrav1.Image{
   276  				ComputeGallery: &infrav1.AzureComputeGalleryImage{
   277  					Gallery: "gallery",
   278  					Name:    "image",
   279  					Version: "version",
   280  				},
   281  			},
   282  		},
   283  		{
   284  			Name: "compute gallery image",
   285  			SDKImageRef: &armcompute.ImageReference{
   286  				ID: ptr.To("/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Compute/galleries/gallery/images/image/versions/version"),
   287  			},
   288  			Image: infrav1.Image{
   289  				ComputeGallery: &infrav1.AzureComputeGalleryImage{
   290  					Gallery:        "gallery",
   291  					Name:           "image",
   292  					Version:        "version",
   293  					SubscriptionID: ptr.To("subscription"),
   294  					ResourceGroup:  ptr.To("rg"),
   295  				},
   296  			},
   297  		},
   298  		{
   299  			Name: "compute gallery image not formatted as expected",
   300  			SDKImageRef: &armcompute.ImageReference{
   301  				ID: ptr.To("/compute/gallery/not/formatted/as/expected"),
   302  			},
   303  			Image: infrav1.Image{
   304  				ID: ptr.To("/compute/gallery/not/formatted/as/expected"),
   305  			},
   306  		},
   307  		{
   308  			Name: "community gallery image not formatted as expected",
   309  			SDKImageRef: &armcompute.ImageReference{
   310  				CommunityGalleryImageID: ptr.To("/community/gallery/not/formatted/as/expected"),
   311  			},
   312  			Image: infrav1.Image{},
   313  		},
   314  	}
   315  
   316  	for _, c := range cases {
   317  		c := c
   318  		t.Run(c.Name, func(t *testing.T) {
   319  			t.Parallel()
   320  			g := gomega.NewGomegaWithT(t)
   321  			g.Expect(converters.SDKImageToImage(c.SDKImageRef, c.IsThirdParty)).To(gomega.Equal(c.Image))
   322  		})
   323  	}
   324  }
   325  
   326  func Test_SDKVMToVMSSVM(t *testing.T) {
   327  	cases := []struct {
   328  		Name     string
   329  		Subject  armcompute.VirtualMachine
   330  		Expected *azure.VMSSVM
   331  	}{
   332  		{
   333  			Name: "minimal VM",
   334  			Subject: armcompute.VirtualMachine{
   335  				ID: ptr.To("vmID1"),
   336  			},
   337  			Expected: &azure.VMSSVM{
   338  				ID: "vmID1",
   339  			},
   340  		},
   341  		{
   342  			Name: "VM with zones",
   343  			Subject: armcompute.VirtualMachine{
   344  				ID: ptr.To("vmID2"),
   345  				Properties: &armcompute.VirtualMachineProperties{
   346  					OSProfile: &armcompute.OSProfile{
   347  						ComputerName: ptr.To("vmwithzones"),
   348  					},
   349  				},
   350  				Zones: []*string{ptr.To("zone0"), ptr.To("zone1")},
   351  			},
   352  			Expected: &azure.VMSSVM{
   353  				ID:               "vmID2",
   354  				Name:             "vmwithzones",
   355  				State:            "Creating",
   356  				AvailabilityZone: "zone0",
   357  			},
   358  		},
   359  		{
   360  			Name: "VM with storage",
   361  			Subject: armcompute.VirtualMachine{
   362  				ID: ptr.To("vmID3"),
   363  				Properties: &armcompute.VirtualMachineProperties{
   364  					OSProfile: &armcompute.OSProfile{
   365  						ComputerName: ptr.To("vmwithstorage"),
   366  					},
   367  					StorageProfile: &armcompute.StorageProfile{
   368  						ImageReference: &armcompute.ImageReference{
   369  							ID: ptr.To("imageID"),
   370  						},
   371  					},
   372  				},
   373  			},
   374  			Expected: &azure.VMSSVM{
   375  				ID: "vmID3",
   376  				Image: infrav1.Image{
   377  					ID: ptr.To("imageID"),
   378  				},
   379  				Name:  "vmwithstorage",
   380  				State: "Creating",
   381  			},
   382  		},
   383  		{
   384  			Name: "VM with provisioning state",
   385  			Subject: armcompute.VirtualMachine{
   386  				ID: ptr.To("vmID4"),
   387  				Properties: &armcompute.VirtualMachineProperties{
   388  					OSProfile: &armcompute.OSProfile{
   389  						ComputerName: ptr.To("vmwithstate"),
   390  					},
   391  					ProvisioningState: ptr.To("Succeeded"),
   392  				},
   393  			},
   394  			Expected: &azure.VMSSVM{
   395  				ID:    "vmID4",
   396  				Name:  "vmwithstate",
   397  				State: "Succeeded",
   398  			},
   399  		},
   400  	}
   401  
   402  	for _, c := range cases {
   403  		c := c
   404  		t.Run(c.Name, func(t *testing.T) {
   405  			t.Parallel()
   406  			g := gomega.NewGomegaWithT(t)
   407  			subject := converters.SDKVMToVMSSVM(c.Subject, "")
   408  			g.Expect(subject).To(gomega.Equal(c.Expected))
   409  		})
   410  	}
   411  }
   412  
   413  func Test_GetOrchestrationMode(t *testing.T) {
   414  	g := gomega.NewGomegaWithT(t)
   415  
   416  	g.Expect(converters.GetOrchestrationMode(infrav1.FlexibleOrchestrationMode)).
   417  		To(gomega.Equal(armcompute.OrchestrationModeFlexible))
   418  	g.Expect(converters.GetOrchestrationMode(infrav1.UniformOrchestrationMode)).
   419  		To(gomega.Equal(armcompute.OrchestrationModeUniform))
   420  	g.Expect(converters.GetOrchestrationMode("invalid")).
   421  		To(gomega.Equal(armcompute.OrchestrationModeUniform))
   422  }