github.com/darmach/terratest@v0.34.8-0.20210517103231-80931f95e3ff/modules/azure/compute.go (about) 1 package azure 2 3 import ( 4 "context" 5 6 "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute" 7 "github.com/gruntwork-io/terratest/modules/testing" 8 "github.com/stretchr/testify/require" 9 ) 10 11 // GetVirtualMachineClient is a helper function that will setup an Azure Virtual Machine client on your behalf. 12 func GetVirtualMachineClient(t testing.TestingT, subscriptionID string) *compute.VirtualMachinesClient { 13 vmClient, err := GetVirtualMachineClientE(subscriptionID) 14 require.NoError(t, err) 15 return vmClient 16 } 17 18 // GetVirtualMachineClientE is a helper function that will setup an Azure Virtual Machine client on your behalf. 19 func GetVirtualMachineClientE(subscriptionID string) (*compute.VirtualMachinesClient, error) { 20 21 // snippet-tag-start::client_factory_example.helper 22 // Create a VM client 23 vmClient, err := CreateVirtualMachinesClientE(subscriptionID) 24 if err != nil { 25 return nil, err 26 } 27 // snippet-tag-end::client_factory_example.helper 28 29 // Create an authorizer 30 authorizer, err := NewAuthorizer() 31 if err != nil { 32 return nil, err 33 } 34 35 // Attach authorizer to the client 36 vmClient.Authorizer = *authorizer 37 return vmClient, nil 38 } 39 40 // VirtualMachineExists indicates whether the specifcied Azure Virtual Machine exists. 41 // This function would fail the test if there is an error. 42 func VirtualMachineExists(t testing.TestingT, vmName string, resGroupName string, subscriptionID string) bool { 43 exists, err := VirtualMachineExistsE(vmName, resGroupName, subscriptionID) 44 require.NoError(t, err) 45 return exists 46 } 47 48 // VirtualMachineExistsE indicates whether the specifcied Azure Virtual Machine exists. 49 func VirtualMachineExistsE(vmName string, resGroupName string, subscriptionID string) (bool, error) { 50 // Get VM Object 51 _, err := GetVirtualMachineE(vmName, resGroupName, subscriptionID) 52 if err != nil { 53 if ResourceNotFoundErrorExists(err) { 54 return false, nil 55 } 56 return false, err 57 } 58 return true, nil 59 } 60 61 // GetVirtualMachineNics gets a list of Network Interface names for a specifcied Azure Virtual Machine. 62 // This function would fail the test if there is an error. 63 func GetVirtualMachineNics(t testing.TestingT, vmName string, resGroupName string, subscriptionID string) []string { 64 nicList, err := GetVirtualMachineNicsE(vmName, resGroupName, subscriptionID) 65 require.NoError(t, err) 66 67 return nicList 68 } 69 70 // GetVirtualMachineNicsE gets a list of Network Interface names for a specified Azure Virtual Machine. 71 func GetVirtualMachineNicsE(vmName string, resGroupName string, subscriptionID string) ([]string, error) { 72 73 // Get VM Object 74 vm, err := GetVirtualMachineE(vmName, resGroupName, subscriptionID) 75 if err != nil { 76 return nil, err 77 } 78 79 // Get VM NIC(s); value always present, no nil checks needed. 80 vmNICs := *vm.NetworkProfile.NetworkInterfaces 81 82 nics := make([]string, len(vmNICs)) 83 for i, nic := range vmNICs { 84 // Get ID from resource string. 85 nicName, err := GetNameFromResourceIDE(*nic.ID) 86 if err == nil { 87 nics[i] = nicName 88 } 89 } 90 return nics, nil 91 } 92 93 // GetVirtualMachineManagedDisks gets the list of Managed Disk names of the specified Azure Virtual Machine. 94 // This function would fail the test if there is an error. 95 func GetVirtualMachineManagedDisks(t testing.TestingT, vmName string, resGroupName string, subscriptionID string) []string { 96 diskNames, err := GetVirtualMachineManagedDisksE(vmName, resGroupName, subscriptionID) 97 require.NoError(t, err) 98 99 return diskNames 100 } 101 102 // GetVirtualMachineManagedDisksE gets the list of Managed Disk names of the specified Azure Virtual Machine. 103 func GetVirtualMachineManagedDisksE(vmName string, resGroupName string, subscriptionID string) ([]string, error) { 104 105 // Get VM Object 106 vm, err := GetVirtualMachineE(vmName, resGroupName, subscriptionID) 107 if err != nil { 108 return nil, err 109 } 110 111 // Get VM attached Disks; value always present even if no disks attached, no nil check needed. 112 vmDisks := *vm.StorageProfile.DataDisks 113 114 // Get the Names of the attached Managed Disks 115 diskNames := make([]string, len(vmDisks)) 116 for i, v := range vmDisks { 117 // Disk names are required, no nil check needed. 118 diskNames[i] = *v.Name 119 } 120 121 return diskNames, nil 122 } 123 124 // GetVirtualMachineOSDiskName gets the OS Disk name of the specified Azure Virtual Machine. 125 // This function would fail the test if there is an error. 126 func GetVirtualMachineOSDiskName(t testing.TestingT, vmName string, resGroupName string, subscriptionID string) string { 127 osDiskName, err := GetVirtualMachineOSDiskNameE(vmName, resGroupName, subscriptionID) 128 require.NoError(t, err) 129 130 return osDiskName 131 } 132 133 // GetVirtualMachineOSDiskNameE gets the OS Disk name of the specified Azure Virtual Machine. 134 func GetVirtualMachineOSDiskNameE(vmName string, resGroupName string, subscriptionID string) (string, error) { 135 // Get VM Object 136 vm, err := GetVirtualMachineE(vmName, resGroupName, subscriptionID) 137 if err != nil { 138 return "", err 139 } 140 141 return *vm.StorageProfile.OsDisk.Name, nil 142 } 143 144 // GetVirtualMachineAvailabilitySetID gets the Availability Set ID of the specified Azure Virtual Machine. 145 // This function would fail the test if there is an error. 146 func GetVirtualMachineAvailabilitySetID(t testing.TestingT, vmName string, resGroupName string, subscriptionID string) string { 147 avsID, err := GetVirtualMachineAvailabilitySetIDE(vmName, resGroupName, subscriptionID) 148 require.NoError(t, err) 149 150 return avsID 151 } 152 153 // GetVirtualMachineAvailabilitySetIDE gets the Availability Set ID of the specified Azure Virtual Machine. 154 func GetVirtualMachineAvailabilitySetIDE(vmName string, resGroupName string, subscriptionID string) (string, error) { 155 // Get VM Object 156 vm, err := GetVirtualMachineE(vmName, resGroupName, subscriptionID) 157 if err != nil { 158 return "", err 159 } 160 161 // Virtual Machine has no associated Availability Set 162 if vm.AvailabilitySet == nil { 163 return "", nil 164 } 165 166 // Get ID from resource string 167 avs, err := GetNameFromResourceIDE(*vm.AvailabilitySet.ID) 168 if err != nil { 169 return "", err 170 } 171 172 return avs, nil 173 } 174 175 // VMImage represents the storage image for the specified Azure Virtual Machine. 176 type VMImage struct { 177 Publisher string 178 Offer string 179 SKU string 180 Version string 181 } 182 183 // GetVirtualMachineImage gets the Image of the specified Azure Virtual Machine. 184 // This function would fail the test if there is an error. 185 func GetVirtualMachineImage(t testing.TestingT, vmName string, resGroupName string, subscriptionID string) VMImage { 186 vmImage, err := GetVirtualMachineImageE(vmName, resGroupName, subscriptionID) 187 require.NoError(t, err) 188 189 return vmImage 190 } 191 192 // GetVirtualMachineImageE gets the Image of the specified Azure Virtual Machine. 193 func GetVirtualMachineImageE(vmName string, resGroupName string, subscriptionID string) (VMImage, error) { 194 var vmImage VMImage 195 196 // Get VM Object 197 vm, err := GetVirtualMachineE(vmName, resGroupName, subscriptionID) 198 if err != nil { 199 return vmImage, err 200 } 201 202 // Populate VM Image; values always present, no nil checks needed 203 vmImage.Publisher = *vm.StorageProfile.ImageReference.Publisher 204 vmImage.Offer = *vm.StorageProfile.ImageReference.Offer 205 vmImage.SKU = *vm.StorageProfile.ImageReference.Sku 206 vmImage.Version = *vm.StorageProfile.ImageReference.Version 207 208 return vmImage, nil 209 } 210 211 // GetSizeOfVirtualMachine gets the Size Type of the specified Azure Virtual Machine. 212 // This function would fail the test if there is an error. 213 func GetSizeOfVirtualMachine(t testing.TestingT, vmName string, resGroupName string, subscriptionID string) compute.VirtualMachineSizeTypes { 214 size, err := GetSizeOfVirtualMachineE(vmName, resGroupName, subscriptionID) 215 require.NoError(t, err) 216 217 return size 218 } 219 220 // GetSizeOfVirtualMachineE gets the Size Type of the specified Azure Virtual Machine. 221 func GetSizeOfVirtualMachineE(vmName string, resGroupName string, subscriptionID string) (compute.VirtualMachineSizeTypes, error) { 222 // Get VM Object 223 vm, err := GetVirtualMachineE(vmName, resGroupName, subscriptionID) 224 if err != nil { 225 return "", err 226 } 227 228 return vm.VirtualMachineProperties.HardwareProfile.VMSize, nil 229 } 230 231 // GetVirtualMachineTags gets the Tags of the specified Virtual Machine as a map. 232 // This function would fail the test if there is an error. 233 func GetVirtualMachineTags(t testing.TestingT, vmName string, resGroupName string, subscriptionID string) map[string]string { 234 tags, err := GetVirtualMachineTagsE(vmName, resGroupName, subscriptionID) 235 require.NoError(t, err) 236 237 return tags 238 } 239 240 // GetVirtualMachineTagsE gets the Tags of the specified Virtual Machine as a map. 241 func GetVirtualMachineTagsE(vmName string, resGroupName string, subscriptionID string) (map[string]string, error) { 242 // Setup a blank map to populate and return 243 tags := make(map[string]string) 244 245 // Get VM Object 246 vm, err := GetVirtualMachineE(vmName, resGroupName, subscriptionID) 247 if err != nil { 248 return tags, err 249 } 250 251 // Range through existing tags and populate above map accordingly 252 for k, v := range vm.Tags { 253 tags[k] = *v 254 } 255 256 return tags, nil 257 } 258 259 // ***************************************************** // 260 // Get multiple Virtual Machines from a Resource Group 261 // ***************************************************** // 262 263 // ListVirtualMachinesForResourceGroup gets a list of all Virtual Machine names in the specified Resource Group. 264 // This function would fail the test if there is an error. 265 func ListVirtualMachinesForResourceGroup(t testing.TestingT, resGroupName string, subscriptionID string) []string { 266 vms, err := ListVirtualMachinesForResourceGroupE(resGroupName, subscriptionID) 267 require.NoError(t, err) 268 return vms 269 } 270 271 // ListVirtualMachinesForResourceGroupE gets a list of all Virtual Machine names in the specified Resource Group. 272 func ListVirtualMachinesForResourceGroupE(resourceGroupName string, subscriptionID string) ([]string, error) { 273 var vmDetails []string 274 275 vmClient, err := GetVirtualMachineClientE(subscriptionID) 276 if err != nil { 277 return nil, err 278 } 279 280 vms, err := vmClient.List(context.Background(), resourceGroupName) 281 if err != nil { 282 return nil, err 283 } 284 285 for _, v := range vms.Values() { 286 vmDetails = append(vmDetails, *v.Name) 287 } 288 return vmDetails, nil 289 } 290 291 // GetVirtualMachinesForResourceGroup gets all Virtual Machine objects in the specified Resource Group. Each 292 // VM Object represents the entire set of VM compute properties accessible by using the VM name as the map key. 293 // This function would fail the test if there is an error. 294 func GetVirtualMachinesForResourceGroup(t testing.TestingT, resGroupName string, subscriptionID string) map[string]compute.VirtualMachineProperties { 295 vms, err := GetVirtualMachinesForResourceGroupE(resGroupName, subscriptionID) 296 require.NoError(t, err) 297 return vms 298 } 299 300 // GetVirtualMachinesForResourceGroupE gets all Virtual Machine objects in the specified Resource Group. Each 301 // VM Object represents the entire set of VM compute properties accessible by using the VM name as the map key. 302 func GetVirtualMachinesForResourceGroupE(resourceGroupName string, subscriptionID string) (map[string]compute.VirtualMachineProperties, error) { 303 // Create VM Client 304 vmClient, err := GetVirtualMachineClientE(subscriptionID) 305 if err != nil { 306 return nil, err 307 } 308 309 // Get the list of VMs in the Resource Group 310 vms, err := vmClient.List(context.Background(), resourceGroupName) 311 if err != nil { 312 return nil, err 313 } 314 315 // Get the VMs in the Resource Group. 316 vmDetails := make(map[string]compute.VirtualMachineProperties, len(vms.Values())) 317 for _, v := range vms.Values() { 318 // VM name and machine properties are required for each VM, no nill check required. 319 vmDetails[*v.Name] = *v.VirtualMachineProperties 320 } 321 return vmDetails, nil 322 } 323 324 // ******************************************************************** // 325 // Get VM using Instance and Instance property get, reducing SKD calls 326 // ******************************************************************** // 327 328 // Instance of the VM 329 type Instance struct { 330 *compute.VirtualMachine 331 } 332 333 // GetVirtualMachineInstanceSize gets the size of the Virtual Machine. 334 func (vm *Instance) GetVirtualMachineInstanceSize() compute.VirtualMachineSizeTypes { 335 return vm.VirtualMachineProperties.HardwareProfile.VMSize 336 } 337 338 // *********************** // 339 // Get the base VM Object 340 // *********************** // 341 342 // GetVirtualMachine gets a Virtual Machine in the specified Azure Resource Group. 343 // This function would fail the test if there is an error. 344 func GetVirtualMachine(t testing.TestingT, vmName string, resGroupName string, subscriptionID string) *compute.VirtualMachine { 345 vm, err := GetVirtualMachineE(vmName, resGroupName, subscriptionID) 346 require.NoError(t, err) 347 return vm 348 } 349 350 // GetVirtualMachineE gets a Virtual Machine in the specified Azure Resource Group. 351 func GetVirtualMachineE(vmName string, resGroupName string, subscriptionID string) (*compute.VirtualMachine, error) { 352 // Validate resource group name and subscription ID 353 resGroupName, err := getTargetAzureResourceGroupName(resGroupName) 354 if err != nil { 355 return nil, err 356 } 357 358 // Get the client reference 359 client, err := GetVirtualMachineClientE(subscriptionID) 360 if err != nil { 361 return nil, err 362 } 363 364 vm, err := client.Get(context.Background(), resGroupName, vmName, compute.InstanceView) 365 if err != nil { 366 return nil, err 367 } 368 369 return &vm, nil 370 }