e2etest/GuestProxyAgentTest/Utilities/VMBuilder.cs (222 lines of code) (raw):
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT
using Azure;
using Azure.Core;
using Azure.ResourceManager;
using Azure.ResourceManager.Compute;
using Azure.ResourceManager.Compute.Models;
using Azure.ResourceManager.Network;
using Azure.ResourceManager.Resources;
using GuestProxyAgentTest.Settings;
using Microsoft.Azure.Management.ResourceManager.Fluent;
namespace GuestProxyAgentTest.Utilities
{
/// <summary>
/// Class for Build an Azure VM based on the test case setting
/// </summary>
class VMBuilder
{
private TestScenarioSetting testScenarioSetting = null!;
private string vmName = "";
private string vNetName = "";
private string netInfName = "";
private string pubIpName = "";
private string rgName = "";
private string adminUsername = "testuser";
private string adminPassword = SdkContext.RandomResourceName("pP@1", 15);
// In order to use the plan, we need to accept the terms first.
// https://learn.microsoft.com/en-us/cli/azure/vm/image/terms?view=azure-cli-latest#az-vm-image-terms-accept
// az vm image terms accept --urn almalinux:almalinux:9:latest --subscription <subscriptionId>
// az vm image terms accept --urn kinvolk:flatcar:stable:latest --subscription <subscriptionId>
// az vm image terms accept --urn resf:rockylinux-x86_64:9-base:latest --subscription <subscriptionId>
private readonly string[] PLAN_REQUIRED_IMAGES = new string[] { "almalinux", "kinvolk", "resf" };
public VMBuilder() { }
/// <summary>
/// Load the test case setting, that set up the virtual machine related resource names, including virtual machine name, virtual network name, network interface name, public ip address name
/// </summary>
/// <param name="testScenarioSetting"></param>
/// <returns></returns>
public VMBuilder LoadTestCaseSetting(TestScenarioSetting testScenarioSetting)
{
this.testScenarioSetting = testScenarioSetting;
this.rgName = this.testScenarioSetting.ResourceGroupName;
var prefix = "e2e" + new Random().Next(1000);
this.vmName = prefix + "vm";
this.vNetName = prefix + "vNet";
this.netInfName = prefix + "nInf";
this.pubIpName = prefix + "pubIp";
return this;
}
/// <summary>
/// Build Build and return the VirtualMachine based on the setting
/// </summary>
/// <returns></returns>
public async Task<VirtualMachineResource> Build(bool enableProxyAgent, CancellationToken cancellationToken)
{
PreCheck();
ArmClient client = new(new GuestProxyAgentE2ETokenCredential(), defaultSubscriptionId: TestSetting.Instance.subscriptionId);
var sub = await client.GetDefaultSubscriptionAsync();
var rgs = sub.GetResourceGroups();
if (await rgs.ExistsAsync(rgName))
{
Console.WriteLine($"Resource group: {rgName} already exists, cleaning it up.");
await (await rgs.GetAsync(rgName)).Value.DeleteAsync(WaitUntil.Completed);
}
Console.WriteLine("Creating resource group: " + rgName);
var rgData = new ResourceGroupData(TestSetting.Instance.location);
rgData.Tags.Add(Constants.COULD_CLEANUP_TAG_NAME, "true");
var rgr = rgs.CreateOrUpdate(WaitUntil.Completed, rgName, rgData).Value;
VirtualMachineCollection vmCollection = rgr.GetVirtualMachines();
Console.WriteLine("Creating virtual machine...");
var vmr = (await vmCollection.CreateOrUpdateAsync(WaitUntil.Completed, this.vmName, await DoCreateVMData(rgr, enableProxyAgent), cancellationToken: cancellationToken)).Value;
Console.WriteLine("Virtual machine created, with id: " + vmr.Id);
return vmr;
}
public async Task<VirtualMachineResource> GetVirtualMachineResource()
{
PreCheck();
ArmClient client = new(new GuestProxyAgentE2ETokenCredential(), defaultSubscriptionId: TestSetting.Instance.subscriptionId);
var sub = await client.GetDefaultSubscriptionAsync();
return sub.GetResourceGroups().Get(this.rgName).Value.GetVirtualMachine(this.vmName);
}
private async Task<VirtualMachineData> DoCreateVMData(ResourceGroupResource rgr, bool enableProxyAgent)
{
var vmData = new VirtualMachineData(TestSetting.Instance.location)
{
HardwareProfile = new VirtualMachineHardwareProfile()
{
VmSize = new VirtualMachineSizeType(TestSetting.Instance.vmSize),
},
StorageProfile = new VirtualMachineStorageProfile()
{
ImageReference = new ImageReference()
{
Publisher = this.testScenarioSetting.VMImageDetails.Publisher,
Offer = this.testScenarioSetting.VMImageDetails.Offer,
Sku = this.testScenarioSetting.VMImageDetails.Sku,
Version = this.testScenarioSetting.VMImageDetails.Version,
},
OSDisk = new VirtualMachineOSDisk(DiskCreateOptionType.FromImage)
{
Name = "e2eVmOsDisk",
Caching = CachingType.ReadWrite,
ManagedDisk = new VirtualMachineManagedDisk()
{
StorageAccountType = StorageAccountType.StandardLrs,
},
},
},
OSProfile = new VirtualMachineOSProfile()
{
ComputerName = vmName,
AdminUsername = this.adminUsername,
AdminPassword = this.adminPassword,
},
NetworkProfile = await DoCreateVMNetWorkProfile(rgr),
};
if (enableProxyAgent)
{
vmData.SecurityProfile = new SecurityProfile()
{
ProxyAgentSettings = new ProxyAgentSettings()
{
Enabled = true,
WireServer = new HostEndpointSettings()
{
InVmAccessControlProfileReferenceId = TestSetting.Instance.InVmWireServerAccessControlProfileReferenceId,
},
Imds = new HostEndpointSettings()
{
InVmAccessControlProfileReferenceId = TestSetting.Instance.InVmIMDSAccessControlProfileReferenceId,
},
}
};
}
if (Constants.IS_WINDOWS())
{
vmData.OSProfile.WindowsConfiguration = new WindowsConfiguration()
{
ProvisionVmAgent = true,
IsAutomaticUpdatesEnabled = true,
PatchSettings = new PatchSettings()
{
AssessmentMode = WindowsPatchAssessmentMode.ImageDefault,
},
};
}
else
{
vmData.OSProfile.LinuxConfiguration = new LinuxConfiguration()
{
//ProvisionVMAgent = true,
//IsPasswordAuthenticationDisabled = false,
};
}
if (PLAN_REQUIRED_IMAGES.Contains(this.testScenarioSetting.VMImageDetails.Publisher))
{
vmData.Plan = new ComputePlan()
{
Name = this.testScenarioSetting.VMImageDetails.Sku,
Publisher = this.testScenarioSetting.VMImageDetails.Publisher,
Product = this.testScenarioSetting.VMImageDetails.Offer,
};
}
return vmData;
}
private async Task<VirtualMachineNetworkProfile> DoCreateVMNetWorkProfile(ResourceGroupResource rgr)
{
Console.WriteLine("Creating network profile");
var vns = rgr.GetVirtualNetworks();
await vns.CreateOrUpdateAsync(WaitUntil.Completed, this.vNetName, new VirtualNetworkData
{
AddressPrefixes =
{
"10.0.0.0/16"
},
FlowTimeoutInMinutes = 10,
Location = TestSetting.Instance.location,
Subnets =
{
new SubnetData
{
Name = "default",
AddressPrefix = "10.0.0.0/24",
DefaultOutboundAccess = false
}
}
});
var pips = rgr.GetPublicIPAddresses();
Console.WriteLine("Creating public ip address.");
await pips.CreateOrUpdateAsync(WaitUntil.Completed, this.pubIpName, new PublicIPAddressData
{
Location = TestSetting.Instance.location
});
var nifs = rgr.GetNetworkInterfaces();
Console.WriteLine("Creating network interface.");
await nifs.CreateOrUpdateAsync(WaitUntil.Completed, this.netInfName, new NetworkInterfaceData()
{
IPConfigurations =
{
new NetworkInterfaceIPConfigurationData()
{
Subnet = new SubnetData()
{
Id = new ResourceIdentifier($"/subscriptions/{TestSetting.Instance.subscriptionId}/resourceGroups/{this.rgName}/providers/Microsoft.Network/virtualNetworks/{this.vNetName}/subnets/default"),
},
PublicIPAddress = new PublicIPAddressData()
{
Id = new ResourceIdentifier($"/subscriptions/{TestSetting.Instance.subscriptionId}/resourceGroups/{this.rgName}/providers/Microsoft.Network/publicIPAddresses/{this.pubIpName}"),
},
Name = "ipconfig1",
}
},
Location = TestSetting.Instance.location,
});
return new VirtualMachineNetworkProfile()
{
NetworkInterfaces =
{
new VirtualMachineNetworkInterfaceReference()
{
Primary = true,
Id = new ResourceIdentifier($"/subscriptions/{TestSetting.Instance.subscriptionId}/resourceGroups/{this.rgName}/providers/Microsoft.Network/networkInterfaces/{this.netInfName}"),
}
},
};
}
private void PreCheck()
{
if (this.testScenarioSetting == null)
{
throw new Exception("missing test case settings");
}
if (TestSetting.Instance == null)
{
throw new Exception("TestSetting not init.");
}
if (StorageHelper.Instance == null)
{
throw new Exception("StorageHelper not init.");
}
}
}
}