diff --git a/src/ApiService/ApiService/ApiService.csproj b/src/ApiService/ApiService/ApiService.csproj
index 26b8ddadd..f2502368d 100644
--- a/src/ApiService/ApiService/ApiService.csproj
+++ b/src/ApiService/ApiService/ApiService.csproj
@@ -24,7 +24,7 @@
-
+
diff --git a/src/ApiService/ApiService/Functions/Proxy.cs b/src/ApiService/ApiService/Functions/Proxy.cs
index 29013507a..74959b12c 100644
--- a/src/ApiService/ApiService/Functions/Proxy.cs
+++ b/src/ApiService/ApiService/Functions/Proxy.cs
@@ -149,7 +149,7 @@ public class Proxy {
return await _context.RequestHandling.NotOk(
req,
request.ErrorV,
- "debug_proxy delet");
+ "debug_proxy delete");
}
var regions = await _context.ProxyForwardOperations.RemoveForward(
diff --git a/src/ApiService/ApiService/Functions/TimerProxy.cs b/src/ApiService/ApiService/Functions/TimerProxy.cs
index 024f8a0b7..e5e89ba2f 100644
--- a/src/ApiService/ApiService/Functions/TimerProxy.cs
+++ b/src/ApiService/ApiService/Functions/TimerProxy.cs
@@ -64,14 +64,16 @@ public class TimerProxy {
// since we do not support bring your own NSG
if (await nsgOpertions.GetNsg(region) != null) {
- var network = await Network.Create(region, _context);
+ var network = await Network.Init(region, _context);
var subnet = await network.GetSubnet();
- var vnet = await network.GetVnet();
- if (subnet != null && vnet != null) {
- var result = await nsgOpertions.AssociateSubnet(region, vnet, subnet);
- if (!result.OkV) {
- _logger.Error($"Failed to associate NSG and subnet due to {result.ErrorV} in region {region}");
+ if (subnet != null) {
+ var vnet = await network.GetVnet();
+ if (vnet != null) {
+ var result = await nsgOpertions.AssociateSubnet(region, vnet, subnet);
+ if (!result.OkV) {
+ _logger.Error($"Failed to associate NSG and subnet due to {result.ErrorV} in region {region}");
+ }
}
}
}
diff --git a/src/ApiService/ApiService/ServiceConfiguration.cs b/src/ApiService/ApiService/ServiceConfiguration.cs
index 5c55ccb62..3eef5dae6 100644
--- a/src/ApiService/ApiService/ServiceConfiguration.cs
+++ b/src/ApiService/ApiService/ServiceConfiguration.cs
@@ -64,47 +64,55 @@ public class ServiceConfiguration : IServiceConfig {
#endif
}
+ private static string? GetEnv(string name) {
+ var v = Environment.GetEnvironmentVariable(name);
+ if (String.IsNullOrEmpty(v))
+ return null;
+
+ return v;
+ }
+
//TODO: Add environment variable to control where to write logs to
public LogDestination[] LogDestinations { get; set; }
//TODO: Get this from Environment variable
public ApplicationInsights.DataContracts.SeverityLevel LogSeverityLevel => ApplicationInsights.DataContracts.SeverityLevel.Verbose;
- public string? ApplicationInsightsAppId => Environment.GetEnvironmentVariable("APPINSIGHTS_APPID");
- public string? ApplicationInsightsInstrumentationKey => Environment.GetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY");
+ public string? ApplicationInsightsAppId => GetEnv("APPINSIGHTS_APPID");
+ public string? ApplicationInsightsInstrumentationKey => GetEnv("APPINSIGHTS_INSTRUMENTATIONKEY");
- public string? AzureSignalRConnectionString => Environment.GetEnvironmentVariable("AzureSignalRConnectionString");
- public string? AzureSignalRServiceTransportType => Environment.GetEnvironmentVariable("AzureSignalRServiceTransportType");
+ public string? AzureSignalRConnectionString => GetEnv("AzureSignalRConnectionString");
+ public string? AzureSignalRServiceTransportType => GetEnv("AzureSignalRServiceTransportType");
- public string? AzureWebJobDisableHomePage { get => Environment.GetEnvironmentVariable("AzureWebJobsDisableHomepage"); }
- public string? AzureWebJobStorage { get => Environment.GetEnvironmentVariable("AzureWebJobsStorage"); }
+ public string? AzureWebJobDisableHomePage { get => GetEnv("AzureWebJobsDisableHomepage"); }
+ public string? AzureWebJobStorage { get => GetEnv("AzureWebJobsStorage"); }
- public string? DiagnosticsAzureBlobContainerSasUrl { get => Environment.GetEnvironmentVariable("DIAGNOSTICS_AZUREBLOBCONTAINERSASURL"); }
- public string? DiagnosticsAzureBlobRetentionDays { get => Environment.GetEnvironmentVariable("DIAGNOSTICS_AZUREBLOBRETENTIONINDAYS"); }
+ public string? DiagnosticsAzureBlobContainerSasUrl { get => GetEnv("DIAGNOSTICS_AZUREBLOBCONTAINERSASURL"); }
+ public string? DiagnosticsAzureBlobRetentionDays { get => GetEnv("DIAGNOSTICS_AZUREBLOBRETENTIONINDAYS"); }
- public string? MultiTenantDomain { get => Environment.GetEnvironmentVariable("MULTI_TENANT_DOMAIN"); }
+ public string? MultiTenantDomain { get => GetEnv("MULTI_TENANT_DOMAIN"); }
- public string? OneFuzzDataStorage { get => Environment.GetEnvironmentVariable("ONEFUZZ_DATA_STORAGE"); }
- public string? OneFuzzFuncStorage { get => Environment.GetEnvironmentVariable("ONEFUZZ_FUNC_STORAGE"); }
- public string? OneFuzzInstance { get => Environment.GetEnvironmentVariable("ONEFUZZ_INSTANCE"); }
- public string? OneFuzzInstanceName { get => Environment.GetEnvironmentVariable("ONEFUZZ_INSTANCE_NAME"); }
- public string? OneFuzzKeyvault { get => Environment.GetEnvironmentVariable("ONEFUZZ_KEYVAULT"); }
- public string? OneFuzzMonitor { get => Environment.GetEnvironmentVariable("ONEFUZZ_MONITOR"); }
- public string? OneFuzzOwner { get => Environment.GetEnvironmentVariable("ONEFUZZ_OWNER"); }
- public string? OneFuzzResourceGroup { get => Environment.GetEnvironmentVariable("ONEFUZZ_RESOURCE_GROUP"); }
- public string? OneFuzzTelemetry { get => Environment.GetEnvironmentVariable("ONEFUZZ_TELEMETRY"); }
+ public string? OneFuzzDataStorage { get => GetEnv("ONEFUZZ_DATA_STORAGE"); }
+ public string? OneFuzzFuncStorage { get => GetEnv("ONEFUZZ_FUNC_STORAGE"); }
+ public string? OneFuzzInstance { get => GetEnv("ONEFUZZ_INSTANCE"); }
+ public string? OneFuzzInstanceName { get => GetEnv("ONEFUZZ_INSTANCE_NAME"); }
+ public string? OneFuzzKeyvault { get => GetEnv("ONEFUZZ_KEYVAULT"); }
+ public string? OneFuzzMonitor { get => GetEnv("ONEFUZZ_MONITOR"); }
+ public string? OneFuzzOwner { get => GetEnv("ONEFUZZ_OWNER"); }
+ public string? OneFuzzResourceGroup { get => GetEnv("ONEFUZZ_RESOURCE_GROUP"); }
+ public string? OneFuzzTelemetry { get => GetEnv("ONEFUZZ_TELEMETRY"); }
public string OneFuzzVersion {
get {
// version can be overridden by config:
- return Environment.GetEnvironmentVariable("ONEFUZZ_VERSION")
+ return GetEnv("ONEFUZZ_VERSION")
?? _oneFuzzVersion
?? throw new InvalidOperationException("Unable to read OneFuzz version from assembly");
}
}
- public string? OneFuzzAllowOutdatedAgent => Environment.GetEnvironmentVariable("ONEFUZZ_ALLOW_OUTDATED_AGENT");
+ public string? OneFuzzAllowOutdatedAgent => GetEnv("ONEFUZZ_ALLOW_OUTDATED_AGENT");
- public string OneFuzzNodeDisposalStrategy { get => Environment.GetEnvironmentVariable("ONEFUZZ_NODE_DISPOSAL_STRATEGY") ?? "scale_in"; }
+ public string OneFuzzNodeDisposalStrategy { get => GetEnv("ONEFUZZ_NODE_DISPOSAL_STRATEGY") ?? "scale_in"; }
public string OneFuzzStoragePrefix => ""; // in production we never prefix the tables
}
diff --git a/src/ApiService/ApiService/onefuzzlib/Creds.cs b/src/ApiService/ApiService/onefuzzlib/Creds.cs
index fe81bef3c..ae0b0e4fd 100644
--- a/src/ApiService/ApiService/onefuzzlib/Creds.cs
+++ b/src/ApiService/ApiService/onefuzzlib/Creds.cs
@@ -122,7 +122,7 @@ public sealed class Creds : ICreds {
var resource = await uid.GetAsync();
var principalId = resource.Value.Data.Properties.ToObjectFromJson().principalId;
- return new Guid(principalId);
+ return Guid.Parse(principalId);
});
}
diff --git a/src/ApiService/ApiService/onefuzzlib/DiskOperations.cs b/src/ApiService/ApiService/onefuzzlib/DiskOperations.cs
index 7e0268947..6225bfeca 100644
--- a/src/ApiService/ApiService/onefuzzlib/DiskOperations.cs
+++ b/src/ApiService/ApiService/onefuzzlib/DiskOperations.cs
@@ -5,7 +5,7 @@ using Azure.ResourceManager.Compute;
namespace Microsoft.OneFuzz.Service;
public interface IDiskOperations {
- DiskImageCollection ListDisks(string resourceGroup);
+ DiskCollection ListDisks(string resourceGroup);
Async.Task DeleteDisk(string resourceGroup, string name);
}
@@ -23,7 +23,7 @@ public class DiskOperations : IDiskOperations {
public async Task DeleteDisk(string resourceGroup, string name) {
try {
_logTracer.Info($"deleting disks {resourceGroup} : {name}");
- var disk = await _creds.GetResourceGroupResource().GetDiskImageAsync(name);
+ var disk = await _creds.GetResourceGroupResource().GetDiskAsync(name);
if (disk != null) {
await disk.Value.DeleteAsync(WaitUntil.Started);
return true;
@@ -35,8 +35,8 @@ public class DiskOperations : IDiskOperations {
return false;
}
- public DiskImageCollection ListDisks(string resourceGroup) {
+ public DiskCollection ListDisks(string resourceGroup) {
_logTracer.Info($"listing disks {resourceGroup}");
- return _creds.GetResourceGroupResource().GetDiskImages();
+ return _creds.GetResourceGroupResource().GetDisks();
}
}
diff --git a/src/ApiService/ApiService/onefuzzlib/Extension.cs b/src/ApiService/ApiService/onefuzzlib/Extension.cs
index 22f8c447f..66836c026 100644
--- a/src/ApiService/ApiService/onefuzzlib/Extension.cs
+++ b/src/ApiService/ApiService/onefuzzlib/Extension.cs
@@ -226,7 +226,8 @@ public class Extensions : IExtensions {
);
var fileName = $"{pool.Name}/config.json";
- await _context.Containers.SaveBlob(new Container("vm-scripts"), fileName, (JsonSerializer.Serialize(config, EntityConverter.GetJsonSerializerOptions())), StorageType.Config);
+ var configJson = JsonSerializer.Serialize(config, EntityConverter.GetJsonSerializerOptions());
+ await _context.Containers.SaveBlob(new Container("vm-scripts"), fileName, configJson, StorageType.Config);
return await ConfigUrl(new Container("vm-scripts"), fileName, false);
}
@@ -264,6 +265,7 @@ public class Extensions : IExtensions {
await UpdateManagedScripts();
var urlsUpdated = urls ?? new();
+ var managedIdentity = JsonSerializer.Serialize(new { ManagedIdentity = new Dictionary() }, _extensionSerializerOptions);
if (vmOs == Os.Windows) {
var vmScripts = await ConfigUrl(new Container("vm-scripts"), "managed.ps1", withSas) ?? throw new Exception("failed to get VmScripts config url");
var toolsAzCopy = await ConfigUrl(new Container("tools"), "win64/azcopy.exe", withSas) ?? throw new Exception("failed to get toolsAzCopy config url");
@@ -286,7 +288,7 @@ public class Extensions : IExtensions {
TypeHandlerVersion = "1.9",
AutoUpgradeMinorVersion = true,
Settings = new BinaryData(JsonSerializer.Serialize(new { commandToExecute = toExecuteCmd, fileUris = urlsUpdated }, _extensionSerializerOptions)),
- ProtectedSettings = new BinaryData(JsonSerializer.Serialize(new { managedIdentity = new Dictionary() }, _extensionSerializerOptions))
+ ProtectedSettings = new BinaryData(managedIdentity)
};
return extension;
} else if (vmOs == Os.Linux) {
@@ -301,7 +303,6 @@ public class Extensions : IExtensions {
var toExecuteCmd = $"sh setup.sh {mode.ToString().ToLowerInvariant()}";
var extensionSettings = JsonSerializer.Serialize(new { CommandToExecute = toExecuteCmd, FileUris = urlsUpdated }, _extensionSerializerOptions);
- var protectedExtensionSettings = JsonSerializer.Serialize(new { ManagedIdentity = new Dictionary() }, _extensionSerializerOptions);
var extension = new VMExtensionWrapper {
Name = "CustomScript",
@@ -312,7 +313,7 @@ public class Extensions : IExtensions {
ForceUpdateTag = Guid.NewGuid().ToString(),
AutoUpgradeMinorVersion = true,
Settings = new BinaryData(extensionSettings),
- ProtectedSettings = new BinaryData(protectedExtensionSettings)
+ ProtectedSettings = new BinaryData(managedIdentity)
};
return extension;
}
diff --git a/src/ApiService/ApiService/onefuzzlib/ImageOperations.cs b/src/ApiService/ApiService/onefuzzlib/ImageOperations.cs
index 81975a388..31ec6a13f 100644
--- a/src/ApiService/ApiService/onefuzzlib/ImageOperations.cs
+++ b/src/ApiService/ApiService/onefuzzlib/ImageOperations.cs
@@ -65,7 +65,7 @@ public class ImageOperations : IImageOperations {
}
} else {
try {
- name = (await _context.Creds.GetResourceGroupResource().GetDiskImages().GetAsync(
+ name = (await _context.Creds.GetResourceGroupResource().GetImages().GetAsync(
parsed.Data.Name
)).Value.Data.StorageProfile.OSDisk.OSType.ToString().ToLowerInvariant();
} catch (Exception ex) when (
@@ -96,15 +96,13 @@ public class ImageOperations : IImageOperations {
version = imageInfo.Version;
}
- var vmImage = await subscription.GetVirtualMachineImageAsync(
- region,
- imageInfo.Publisher,
- imageInfo.Offer,
- imageInfo.Sku
- , version
- );
-
- name = vmImage.Value.OSDiskImageOperatingSystem!.Value.ToString().ToLower();
+ name = (await subscription.GetVirtualMachineImageAsync(
+ region,
+ imageInfo.Publisher,
+ imageInfo.Offer,
+ imageInfo.Sku
+ , version
+ )).Value.OSDiskImageOperatingSystem.ToString().ToLower();
} catch (RequestFailedException ex) {
return OneFuzzResult.Error(
ErrorCode.INVALID_IMAGE,
diff --git a/src/ApiService/ApiService/onefuzzlib/IpOperations.cs b/src/ApiService/ApiService/onefuzzlib/IpOperations.cs
index 740963dff..fb4330e13 100644
--- a/src/ApiService/ApiService/onefuzzlib/IpOperations.cs
+++ b/src/ApiService/ApiService/onefuzzlib/IpOperations.cs
@@ -16,6 +16,8 @@ public interface IIpOperations {
public Async.Task GetPublicIp(ResourceIdentifier resourceId);
+ public Async.Task GetPublicIp(string resourceId);
+
public Async.Task GetIp(string resourceGroup, string name);
public Async.Task DeleteNic(string resourceGroup, string name);
@@ -86,6 +88,9 @@ public class IpOperations : IIpOperations {
var ips = await _networkInterfaceQuery.ListInstancePrivateIps(scalesetId, instance.OkV);
return ips.FirstOrDefault();
}
+ public async Task GetPublicIp(string resourceId) {
+ return await GetPublicIp(new ResourceIdentifier(resourceId));
+ }
public async Task GetPublicIp(ResourceIdentifier resourceId) {
// TODO: Parts of this function seem redundant, but I'm mirroring
@@ -117,12 +122,15 @@ public class IpOperations : IIpOperations {
public async Task CreatePublicNic(string resourceGroup, string name, string region, Nsg? nsg) {
_logTracer.Info($"creating nic for {resourceGroup}:{name} in {region}");
- var network = await Network.Create(region, _context);
+ var network = await Network.Init(region, _context);
var subnetId = await network.GetId();
if (subnetId is null) {
- await network.Create();
- return OneFuzzResultVoid.Ok;
+ var r = await network.Create();
+ if (!r.IsOk) {
+ _logTracer.Error($"failed to create network in region {region} due to {r.ErrorV}");
+ }
+ return r;
}
if (nsg != null) {
diff --git a/src/ApiService/ApiService/onefuzzlib/Network.cs b/src/ApiService/ApiService/onefuzzlib/Network.cs
index 9efdd28db..f170fc38b 100644
--- a/src/ApiService/ApiService/onefuzzlib/Network.cs
+++ b/src/ApiService/ApiService/onefuzzlib/Network.cs
@@ -22,7 +22,7 @@ public class Network {
_networkConfig = networkConfig;
}
- public static async Async.Task Create(string region, IOnefuzzContext context) {
+ public static async Async.Task Init(string region, IOnefuzzContext context) {
var group = context.Creds.GetBaseResourceGroup();
var instanceConfig = await context.ConfigOperations.Fetch();
var networkConfig = instanceConfig.NetworkConfig;
diff --git a/src/ApiService/ApiService/onefuzzlib/ProxyOperations.cs b/src/ApiService/ApiService/onefuzzlib/ProxyOperations.cs
index 3f4a774e6..4754e509b 100644
--- a/src/ApiService/ApiService/onefuzzlib/ProxyOperations.cs
+++ b/src/ApiService/ApiService/onefuzzlib/ProxyOperations.cs
@@ -217,7 +217,7 @@ public class ProxyOperations : StatefulOrm, IPr
}
foreach (var status in instanceView.Statuses) {
- if (status.Level == ComputeStatusLevelType.Error) {
+ if (status.Level == StatusLevelTypes.Error) {
yield return $"code:{status.Code} status:{status.DisplayStatus} message:{status.Message}";
}
}
diff --git a/src/ApiService/ApiService/onefuzzlib/ScalesetOperations.cs b/src/ApiService/ApiService/onefuzzlib/ScalesetOperations.cs
index 1a68363be..2f2fe602f 100644
--- a/src/ApiService/ApiService/onefuzzlib/ScalesetOperations.cs
+++ b/src/ApiService/ApiService/onefuzzlib/ScalesetOperations.cs
@@ -198,7 +198,7 @@ public class ScalesetOperations : StatefulOrm GetSubnet(string vnetName, string subnetName) {
- var vnet = await this.GetVnet(vnetName);
+ try {
+ var vnet = await this.GetVnet(vnetName);
- if (vnet != null) {
- return await vnet.GetSubnetAsync(subnetName);
+ if (vnet != null) {
+ return await vnet.GetSubnetAsync(subnetName);
+ }
+ return null;
+ } catch (RequestFailedException ex) when (ex.Status == 404) {
+ return null;
}
- return null;
+
}
public async Task GetSubnetId(string name, string subnetName) {
diff --git a/src/ApiService/ApiService/onefuzzlib/VmExtensionWrapper.cs b/src/ApiService/ApiService/onefuzzlib/VmExtensionWrapper.cs
index a017f0dce..e0f86cccb 100644
--- a/src/ApiService/ApiService/onefuzzlib/VmExtensionWrapper.cs
+++ b/src/ApiService/ApiService/onefuzzlib/VmExtensionWrapper.cs
@@ -1,6 +1,7 @@
using Azure.Core;
using Azure.ResourceManager.Compute;
+
namespace Microsoft.OneFuzz.Service {
public class VMExtensionWrapper {
public AzureLocation? Location { get; init; }
@@ -27,7 +28,7 @@ namespace Microsoft.OneFuzz.Service {
var protectedSettings = ProtectedSettings ?? new BinaryData(new Dictionary());
return (Name!, new VirtualMachineExtensionData(Location.Value) {
- ExtensionType = TypePropertiesType,
+ TypePropertiesType = TypePropertiesType,
Publisher = Publisher,
TypeHandlerVersion = TypeHandlerVersion,
AutoUpgradeMinorVersion = AutoUpgradeMinorVersion,
@@ -49,7 +50,8 @@ namespace Microsoft.OneFuzz.Service {
var protectedSettings = ProtectedSettings ?? new BinaryData(new Dictionary());
return new VirtualMachineScaleSetExtensionData() {
- ExtensionType = TypePropertiesType,
+ Name = Name,
+ TypePropertiesType = TypePropertiesType,
Publisher = Publisher,
TypeHandlerVersion = TypeHandlerVersion,
AutoUpgradeMinorVersion = AutoUpgradeMinorVersion,
@@ -62,3 +64,4 @@ namespace Microsoft.OneFuzz.Service {
}
}
+
diff --git a/src/ApiService/ApiService/onefuzzlib/VmOperations.cs b/src/ApiService/ApiService/onefuzzlib/VmOperations.cs
index 2f2509dfa..f9f8f994c 100644
--- a/src/ApiService/ApiService/onefuzzlib/VmOperations.cs
+++ b/src/ApiService/ApiService/onefuzzlib/VmOperations.cs
@@ -1,6 +1,5 @@
using System.Threading.Tasks;
using Azure;
-using Azure.Core;
using Azure.ResourceManager.Compute;
using Azure.ResourceManager.Compute.Models;
using Newtonsoft.Json;
@@ -68,7 +67,7 @@ public class VmOperations : IVmOperations {
public async Task GetVm(string name) {
// _logTracer.Debug($"getting vm: {name}");
try {
- var result = await _context.Creds.GetResourceGroupResource().GetVirtualMachineAsync(name, InstanceViewType.InstanceView);
+ var result = await _context.Creds.GetResourceGroupResource().GetVirtualMachineAsync(name, InstanceViewTypes.InstanceView);
if (result == null) {
return null;
}
@@ -256,20 +255,20 @@ public class VmOperations : IVmOperations {
}
var vmParams = new VirtualMachineData(location) {
- OSProfile = new VirtualMachineOSProfile {
+ OSProfile = new OSProfile {
ComputerName = "node",
AdminUsername = "onefuzz",
},
- HardwareProfile = new VirtualMachineHardwareProfile {
+ HardwareProfile = new HardwareProfile {
VmSize = vmSku,
},
- StorageProfile = new VirtualMachineStorageProfile {
+ StorageProfile = new StorageProfile {
ImageReference = GenerateImageReference(image),
},
- NetworkProfile = new VirtualMachineNetworkProfile(),
+ NetworkProfile = new NetworkProfile(),
};
- vmParams.NetworkProfile.NetworkInterfaces.Add(new VirtualMachineNetworkInterfaceReference { Id = nic.Id });
+ vmParams.NetworkProfile.NetworkInterfaces.Add(new NetworkInterfaceReference { Id = nic.Id });
var imageOs = await _context.ImageOperations.GetOs(location, image);
if (!imageOs.IsOk) {
@@ -286,7 +285,7 @@ public class VmOperations : IVmOperations {
DisablePasswordAuthentication = true,
};
vmParams.OSProfile.LinuxConfiguration.SshPublicKeys.Add(
- new SshPublicKeyConfiguration {
+ new SshPublicKeyInfo {
Path = "/home/onefuzz/.ssh/authorized_keys",
KeyData = sshPublicKey
}
@@ -333,7 +332,7 @@ public class VmOperations : IVmOperations {
var imageRef = new ImageReference();
if (image.StartsWith("/", StringComparison.Ordinal)) {
- imageRef.Id = new ResourceIdentifier(image);
+ imageRef.Id = image;
} else {
var imageVal = image.Split(":", 4);
imageRef.Publisher = imageVal[0];
diff --git a/src/ApiService/ApiService/onefuzzlib/VmssOperations.cs b/src/ApiService/ApiService/onefuzzlib/VmssOperations.cs
index 62d727112..5d556feea 100644
--- a/src/ApiService/ApiService/onefuzzlib/VmssOperations.cs
+++ b/src/ApiService/ApiService/onefuzzlib/VmssOperations.cs
@@ -262,15 +262,15 @@ public class VmssOperations : IVmssOperations {
Sku = new ComputeSku() { Name = vmSku, Capacity = vmCount },
Overprovision = false,
SinglePlacementGroup = false,
- UpgradePolicy = new VirtualMachineScaleSetUpgradePolicy() { Mode = VirtualMachineScaleSetUpgradeMode.Manual },
+ UpgradePolicy = new UpgradePolicy() { Mode = UpgradeMode.Manual },
Identity = new ManagedServiceIdentity(managedServiceIdentityType: ManagedServiceIdentityType.UserAssigned),
};
vmssData.Identity.UserAssignedIdentities.Add(_creds.GetScalesetIdentityResourcePath(), new UserAssignedIdentity());
- vmssData.VirtualMachineProfile = new VirtualMachineScaleSetVmProfile() { Priority = VirtualMachinePriorityType.Regular };
+ vmssData.VirtualMachineProfile = new VirtualMachineScaleSetVmProfile() { Priority = VirtualMachinePriorityTypes.Regular };
var imageRef = new ImageReference();
if (image.StartsWith('/')) {
- imageRef.Id = new ResourceIdentifier(image);
+ imageRef.Id = image;
} else {
var info = IImageOperations.GetImageInfo(image);
imageRef.Publisher = info.Publisher;
@@ -303,7 +303,7 @@ public class VmssOperations : IVmssOperations {
case Os.Linux:
vmssData.VirtualMachineProfile.OSProfile.LinuxConfiguration = new LinuxConfiguration();
vmssData.VirtualMachineProfile.OSProfile.LinuxConfiguration.DisablePasswordAuthentication = true;
- var i = new SshPublicKeyConfiguration() { KeyData = sshPublicKey, Path = "/home/onefuzz/.ssh/authorized_keys" };
+ var i = new SshPublicKeyInfo() { KeyData = sshPublicKey, Path = "/home/onefuzz/.ssh/authorized_keys" };
vmssData.VirtualMachineProfile.OSProfile.LinuxConfiguration.SshPublicKeys.Add(i);
break;
default:
@@ -311,10 +311,10 @@ public class VmssOperations : IVmssOperations {
}
if (ephemeralOsDisks) {
- vmssData.VirtualMachineProfile.StorageProfile.OSDisk = new VirtualMachineScaleSetOSDisk(DiskCreateOptionType.FromImage);
+ vmssData.VirtualMachineProfile.StorageProfile.OSDisk = new VirtualMachineScaleSetOSDisk(DiskCreateOptionTypes.FromImage);
vmssData.VirtualMachineProfile.StorageProfile.OSDisk.DiffDiskSettings = new DiffDiskSettings();
- vmssData.VirtualMachineProfile.StorageProfile.OSDisk.DiffDiskSettings.Option = DiffDiskOption.Local;
- vmssData.VirtualMachineProfile.StorageProfile.OSDisk.Caching = CachingType.ReadOnly;
+ vmssData.VirtualMachineProfile.StorageProfile.OSDisk.DiffDiskSettings.Option = DiffDiskOptions.Local;
+ vmssData.VirtualMachineProfile.StorageProfile.OSDisk.Caching = CachingTypes.ReadOnly;
}
if (spotInstance.HasValue && spotInstance.Value) {
@@ -323,8 +323,8 @@ public class VmssOperations : IVmssOperations {
//
// https://docs.microsoft.com/en-us/azure/
// virtual-machine-scale-sets/use-spot#resource-manager-templates
- vmssData.VirtualMachineProfile.EvictionPolicy = VirtualMachineEvictionPolicyType.Deallocate;
- vmssData.VirtualMachineProfile.Priority = VirtualMachinePriorityType.Spot;
+ vmssData.VirtualMachineProfile.EvictionPolicy = VirtualMachineEvictionPolicyTypes.Deallocate;
+ vmssData.VirtualMachineProfile.Priority = VirtualMachinePriorityTypes.Spot;
vmssData.VirtualMachineProfile.BillingMaxPrice = 1.0;
}
@@ -370,14 +370,14 @@ public class VmssOperations : IVmssOperations {
entry.SetAbsoluteExpiration(TimeSpan.FromMinutes(10));
var sub = _creds.GetSubscriptionResource();
- var skus = sub.GetComputeResourceSkusAsync(filter: TableClient.CreateQueryFilter($"location eq '{region}'"));
+ var skus = sub.GetResourceSkusAsync(filter: TableClient.CreateQueryFilter($"location eq '{region}'"));
var skuNames = new List();
await foreach (var sku in skus) {
var available = true;
if (sku.Restrictions is not null) {
foreach (var restriction in sku.Restrictions) {
- if (restriction.RestrictionsType == ComputeResourceSkuRestrictionsType.Location &&
+ if (restriction.RestrictionsType == ResourceSkuRestrictionsType.Location &&
restriction.Values.Contains(region, StringComparer.OrdinalIgnoreCase)) {
available = false;
break;
diff --git a/src/ApiService/ApiService/packages.lock.json b/src/ApiService/ApiService/packages.lock.json
index f85a70138..f990631d9 100644
--- a/src/ApiService/ApiService/packages.lock.json
+++ b/src/ApiService/ApiService/packages.lock.json
@@ -65,12 +65,12 @@
},
"Azure.ResourceManager.Compute": {
"type": "Direct",
- "requested": "[1.0.0, )",
- "resolved": "1.0.0",
- "contentHash": "dmDhokNFcyreIYZMkha8OsLmch0hW/sdOA2nxN4MPVd8KJgGWB8DxCZWwG7qhh59RInKtmWOP8BnBS5mN+W5wQ==",
+ "requested": "[1.0.0-beta.8, )",
+ "resolved": "1.0.0-beta.8",
+ "contentHash": "rYYjjmEdmcOa8O4UgO/bdJ/qQclNZjuHdalxRJ0AhUHCORcM1f1BbIKR9CoN83IpfuEE+X+n5XY9QZcKvfrGVA==",
"dependencies": {
- "Azure.Core": "1.25.0",
- "Azure.ResourceManager": "1.2.0",
+ "Azure.Core": "1.24.0",
+ "Azure.ResourceManager": "1.0.0",
"System.Text.Json": "4.7.2"
}
},
diff --git a/src/ApiService/FunctionalTests/1f-api/ApiBase.cs b/src/ApiService/FunctionalTests/1f-api/ApiBase.cs
index 5a8531d93..5c32551ba 100644
--- a/src/ApiService/FunctionalTests/1f-api/ApiBase.cs
+++ b/src/ApiService/FunctionalTests/1f-api/ApiBase.cs
@@ -5,11 +5,11 @@ using Xunit.Abstractions;
namespace FunctionalTests;
-interface IFromJsonElement {
+public interface IFromJsonElement {
T Convert(JsonElement e);
}
-class BooleanResult : IFromJsonElement {
+public class BooleanResult : IFromJsonElement {
JsonElement _e;
public BooleanResult() { }
public BooleanResult(JsonElement e) => _e = e;
@@ -19,7 +19,7 @@ class BooleanResult : IFromJsonElement {
public BooleanResult Convert(JsonElement e) => new BooleanResult(e);
}
-abstract class ApiBase {
+public abstract class ApiBase {
Uri _endpoint;
Microsoft.OneFuzz.Service.Request _request;
diff --git a/src/ApiService/FunctionalTests/1f-api/Error.cs b/src/ApiService/FunctionalTests/1f-api/Error.cs
index 9fb5f2264..be2a82602 100644
--- a/src/ApiService/FunctionalTests/1f-api/Error.cs
+++ b/src/ApiService/FunctionalTests/1f-api/Error.cs
@@ -3,7 +3,7 @@ using Xunit;
namespace FunctionalTests;
-class Error : IComparable, IFromJsonElement {
+public class Error : IComparable, IFromJsonElement {
JsonElement _e;
public Error(JsonElement e) {
@@ -21,18 +21,18 @@ class Error : IComparable, IFromJsonElement {
return res.ValueKind == JsonValueKind.Object && res.TryGetProperty("code", out _) && res.TryGetProperty("errors", out _);
}
- public int CompareTo(Error? error) {
- if (error is null) {
+ public int CompareTo(Error? other) {
+ if (other is null) {
return -1;
}
- var sameErrorMessages = Errors.Count() == error.Errors.Count();
- foreach (var s in error.Errors) {
+ var sameErrorMessages = Errors.Count() == other.Errors.Count();
+ foreach (var s in other.Errors) {
if (!sameErrorMessages) break;
sameErrorMessages = Errors.Contains(s);
}
- if (error.Code == this.Code && sameErrorMessages) {
+ if (other.Code == this.Code && sameErrorMessages) {
return 0;
} else
return 1;
diff --git a/src/ApiService/FunctionalTests/1f-api/Helpers.cs b/src/ApiService/FunctionalTests/1f-api/Helpers.cs
new file mode 100644
index 000000000..42e21a5e7
--- /dev/null
+++ b/src/ApiService/FunctionalTests/1f-api/Helpers.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace FunctionalTests {
+ public class Helpers {
+
+ public static async Task<(Pool, Scaleset)> CreatePoolAndScaleset(PoolApi poolApi, ScalesetApi scalesetApi, string os = "linux", string? region = null, int numNodes = 2) {
+ var image = (os == "linux") ? ScalesetApi.Image_Ubuntu_20_04 : ScalesetApi.ImageWindows;
+
+ var newPoolId = Guid.NewGuid().ToString();
+ var newPoolName = PoolApi.TestPoolPrefix + newPoolId;
+ var newPool = await poolApi.Create(newPoolName, os);
+
+ Assert.True(newPool.IsOk, $"failed to create new pool: {newPool.ErrorV}");
+ var newScalesetResult = await scalesetApi.Create(newPool.OkV!.Name, numNodes, region: region, image: image);
+
+ Assert.True(newScalesetResult.IsOk, $"failed to crate new scaleset: {newScalesetResult.ErrorV}");
+ var newScaleset = newScalesetResult.OkV!;
+
+ return (newPool.OkV!, newScaleset);
+
+ }
+ }
+}
diff --git a/src/ApiService/FunctionalTests/1f-api/Node.cs b/src/ApiService/FunctionalTests/1f-api/Node.cs
index cba877fa0..a814f4a03 100644
--- a/src/ApiService/FunctionalTests/1f-api/Node.cs
+++ b/src/ApiService/FunctionalTests/1f-api/Node.cs
@@ -5,7 +5,7 @@ using Xunit.Abstractions;
namespace FunctionalTests;
-class Node : IFromJsonElement {
+public class Node : IFromJsonElement {
JsonElement _e;
public Node() { }
@@ -35,19 +35,19 @@ class Node : IFromJsonElement {
}
-class NodeApi : ApiBase {
+public class NodeApi : ApiBase {
public NodeApi(Uri endpoint, Microsoft.OneFuzz.Service.Request request, ITestOutputHelper output) :
base(endpoint, "/api/Node", request, output) {
}
- public async Task Update(Guid machineId, bool? debugKeepNode = null) {
+ public async Task Update(Guid machineId, bool? debugKeepNode = null) {
var j = new JsonObject();
if (debugKeepNode is not null)
j.Add("debug_keep_node", JsonValue.Create(debugKeepNode));
j.Add("machine_id", JsonValue.Create(machineId));
- return await Post(j);
+ return Return(await Post(j));
}
public async Task, Error>> Get(Guid? machineId = null, List? state = null, Guid? scalesetId = null, string? poolName = null) {
var j = new JsonObject();
@@ -66,10 +66,10 @@ class NodeApi : ApiBase {
return IEnumerableResult(await Get(j));
}
- public async Task Patch(Guid machineId) {
+ public async Task Patch(Guid machineId) {
var j = new JsonObject();
j.Add("machine_id", JsonValue.Create(machineId));
- return await Patch(j);
+ return Return(await Patch(j));
}
public async Task Delete(Guid machineId) {
diff --git a/src/ApiService/FunctionalTests/1f-api/Pool.cs b/src/ApiService/FunctionalTests/1f-api/Pool.cs
index c9062c778..ce5a61e61 100644
--- a/src/ApiService/FunctionalTests/1f-api/Pool.cs
+++ b/src/ApiService/FunctionalTests/1f-api/Pool.cs
@@ -5,7 +5,7 @@ using Xunit.Abstractions;
namespace FunctionalTests;
-class Pool : IFromJsonElement {
+public class Pool : IFromJsonElement {
JsonElement _e;
@@ -19,26 +19,30 @@ class Pool : IFromJsonElement {
public Pool Convert(JsonElement e) => new Pool(e);
}
-class PoolApi : ApiBase {
+public class PoolApi : ApiBase {
- public static string TestPoolPrefix = "FT-DELETE-";
+ public const string TestPoolPrefix = "FT-DELETE-";
public PoolApi(Uri endpoint, Microsoft.OneFuzz.Service.Request request, ITestOutputHelper output) :
base(endpoint, "/api/Pool", request, output) {
}
public async Task Delete(string name, bool now = true) {
+ _output.WriteLine($"deleting pool: {name}, now: {now}");
var root = new JsonObject();
root.Add("name", JsonValue.Create(name));
root.Add("now", JsonValue.Create(now));
return Return(await Delete(root));
}
- public async Task, Error>> Get(string? poolName = null, string? poolId = null, string? state = null) {
+ public async Task, Error>> Get(string? name = null, string? id = null, string? state = null) {
var root = new JsonObject();
- root.Add("pool_id", poolId);
- root.Add("name", poolName);
- root.Add("state", state);
+ if (id is not null)
+ root.Add("pool_id", id);
+ if (name is not null)
+ root.Add("name", name);
+ if (state is not null)
+ root.Add("state", state);
var res = await Get(root);
return IEnumerableResult(res);
@@ -52,7 +56,6 @@ class PoolApi : ApiBase {
foreach (var pool in pools.OkV) {
if (pool.Name.StartsWith(TestPoolPrefix)) {
- _output.WriteLine($"Deleting {pool.Name}");
var deleted = await Delete(pool.Name);
Assert.True(deleted.Result);
}
@@ -60,6 +63,8 @@ class PoolApi : ApiBase {
}
public async Task> Create(string poolName, string os, string arch = "x86_64") {
+ _output.WriteLine($"creating new pool {poolName} os: {os}");
+
var rootPoolCreate = new JsonObject();
rootPoolCreate.Add("name", poolName);
rootPoolCreate.Add("os", os);
diff --git a/src/ApiService/FunctionalTests/1f-api/Proxy.cs b/src/ApiService/FunctionalTests/1f-api/Proxy.cs
index c4a512557..98f51a676 100644
--- a/src/ApiService/FunctionalTests/1f-api/Proxy.cs
+++ b/src/ApiService/FunctionalTests/1f-api/Proxy.cs
@@ -3,9 +3,7 @@ using System.Text.Json.Nodes;
using Xunit.Abstractions;
namespace FunctionalTests;
-
-
-class Proxy : IFromJsonElement {
+public class Proxy : IFromJsonElement {
JsonElement _e;
public Proxy() { }
@@ -19,8 +17,7 @@ class Proxy : IFromJsonElement {
public Proxy Convert(JsonElement e) => new Proxy(e);
}
-
-class Forward : IFromJsonElement, IComparable {
+public class Forward : IFromJsonElement, IComparable {
JsonElement _e;
public Forward() { }
public Forward(JsonElement e) => _e = e;
@@ -43,14 +40,27 @@ class Forward : IFromJsonElement, IComparable {
}
}
-class ProxyGetResult : IFromJsonElement, IComparable {
+public class ProxyGetResult : IFromJsonElement, IComparable {
JsonElement _e;
public ProxyGetResult() { }
public ProxyGetResult(JsonElement e) => _e = e;
- public string? Ip => _e.ValueKind == JsonValueKind.Null ? null : _e.GetProperty("ip").GetString();
+ public string? Ip {
+ get {
+ JsonElement ip;
+ if (_e.TryGetProperty("ip", out ip)) {
+ if (ip.ValueKind == JsonValueKind.Null) {
+ return null;
+ } else {
+ return ip.GetString();
+ }
+ } else {
+ return null;
+ }
+ }
+ }
public Forward Forward => new Forward(_e.GetProperty("forward"));
@@ -76,7 +86,7 @@ class ProxyGetResult : IFromJsonElement, IComparable, Error>> Get(Guid? scalesetId = null, Guid? machineId = null, int? dstPort = null) {
var root = new JsonObject();
- root.Add("scaleset_id", scalesetId);
- root.Add("machine_id", machineId);
- root.Add("dst_port", dstPort);
+ if (scalesetId is not null)
+ root.Add("scaleset_id", scalesetId);
+ if (machineId is not null)
+ root.Add("machine_id", machineId);
+ if (dstPort is not null)
+ root.Add("dst_port", dstPort);
var r = await Get(root);
if (Error.IsError(r)) {
diff --git a/src/ApiService/FunctionalTests/1f-api/Scaleset.cs b/src/ApiService/FunctionalTests/1f-api/Scaleset.cs
index cd9548231..969e913f4 100644
--- a/src/ApiService/FunctionalTests/1f-api/Scaleset.cs
+++ b/src/ApiService/FunctionalTests/1f-api/Scaleset.cs
@@ -4,10 +4,7 @@ using Xunit;
using Xunit.Abstractions;
namespace FunctionalTests;
-
-
-
-class Authentication {
+public class Authentication {
JsonElement _e;
public Authentication() { }
@@ -20,7 +17,7 @@ class Authentication {
}
-class ScalesetNodeState {
+public class ScalesetNodeState {
JsonElement _e;
public ScalesetNodeState() { }
@@ -32,7 +29,7 @@ class ScalesetNodeState {
public string? NodeState => _e.GetProperty("state").GetString();
}
-class Scaleset : IFromJsonElement {
+public class Scaleset : IFromJsonElement {
JsonElement _e;
public Scaleset() { }
public Scaleset(JsonElement e) => _e = e;
@@ -68,9 +65,10 @@ class Scaleset : IFromJsonElement {
public Scaleset Convert(JsonElement e) => new Scaleset(e);
}
-class ScalesetApi : ApiBase {
+public class ScalesetApi : ApiBase {
public const string Image_Ubuntu_20_04 = "Canonical:0001-com-ubuntu-server-focal:20_04-lts:latest";
+ public const string ImageWindows = "MicrosoftWindowsDesktop:Windows-10:win10-21h2-pro:latest";
public ScalesetApi(Uri endpoint, Microsoft.OneFuzz.Service.Request request, ITestOutputHelper output) :
base(endpoint, "/api/Scaleset", request, output) { }
@@ -78,20 +76,26 @@ class ScalesetApi : ApiBase {
public async Task, Error>> Get(Guid? id = null, string? state = null, bool? includeAuth = false) {
var root = new JsonObject();
- root.Add("scaleset_id", id);
- root.Add("state", state);
- root.Add("include_auth", includeAuth);
+ if (id is not null)
+ root.Add("scaleset_id", id);
+ if (state is not null)
+ root.Add("state", state);
+ if (includeAuth is not null)
+ root.Add("include_auth", includeAuth);
var res = await Get(root);
return IEnumerableResult(res);
}
- public async Task> Create(string poolName, int size, string vmSku = "Standard_D2s_v3", string image = Image_Ubuntu_20_04, bool spotInstance = false) {
+ public async Task> Create(string poolName, int size, string? region = null, string vmSku = "Standard_D2s_v3", string image = Image_Ubuntu_20_04, bool spotInstance = false) {
+ _output.WriteLine($"Creating scaleset in pool {poolName}, size: {size}");
var rootScalesetCreate = new JsonObject();
rootScalesetCreate.Add("pool_name", poolName);
rootScalesetCreate.Add("vm_sku", vmSku);
rootScalesetCreate.Add("image", image);
rootScalesetCreate.Add("size", size);
- rootScalesetCreate.Add("spot_instance", spotInstance);
+ rootScalesetCreate.Add("spot_instances", spotInstance);
+ if (region is not null)
+ rootScalesetCreate.Add("region", region);
var tags = new JsonObject();
tags.Add("Purpose", "Functional-Test");
diff --git a/src/ApiService/FunctionalTests/GlobalSuppressions.cs b/src/ApiService/FunctionalTests/GlobalSuppressions.cs
index 537cde53b..6425018ac 100644
--- a/src/ApiService/FunctionalTests/GlobalSuppressions.cs
+++ b/src/ApiService/FunctionalTests/GlobalSuppressions.cs
@@ -6,3 +6,6 @@
using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Style", "IDE0005:Using directive is unnecessary.", Justification = "Test code")]
+[assembly: SuppressMessage("Design", "CA1036:Override methods on comparable types", Justification = "Test code", Scope = "type", Target = "~T:FunctionalTests.Error")]
+[assembly: SuppressMessage("Design", "CA1036:Override methods on comparable types", Justification = "Test code", Scope = "type", Target = "~T:FunctionalTests.Forward")]
+[assembly: SuppressMessage("Design", "CA1036:Override methods on comparable types", Justification = "Test code", Scope = "type", Target = "~T:FunctionalTests.ProxyGetResult")]
diff --git a/src/ApiService/FunctionalTests/TestNode.cs b/src/ApiService/FunctionalTests/TestNode.cs
index 0994249b1..781996b54 100644
--- a/src/ApiService/FunctionalTests/TestNode.cs
+++ b/src/ApiService/FunctionalTests/TestNode.cs
@@ -8,11 +8,15 @@ namespace FunctionalTests {
public class TestNode {
NodeApi _nodeApi;
+ ScalesetApi _scalesetApi;
+ PoolApi _poolApi;
private readonly ITestOutputHelper _output;
public TestNode(ITestOutputHelper output) {
_output = output;
_nodeApi = new NodeApi(ApiClient.Endpoint, ApiClient.Request, output);
+ _scalesetApi = new ScalesetApi(ApiClient.Endpoint, ApiClient.Request, output);
+ _poolApi = new PoolApi(ApiClient.Endpoint, ApiClient.Request, output);
}
[Fact]
@@ -34,5 +38,32 @@ namespace FunctionalTests {
}
+ [Fact]
+ async Task GetPatchPostDelete() {
+
+ var (pool, scaleset) = await Helpers.CreatePoolAndScaleset(_poolApi, _scalesetApi, "linux");
+
+ scaleset = await _scalesetApi.WaitWhile(scaleset.ScalesetId, sc => sc.State == "init" || sc.State == "setup");
+ Assert.True(scaleset.Nodes!.Count > 0);
+
+ var nodeState = scaleset.Nodes!.First();
+ var nodeResult = await _nodeApi.Get(nodeState.MachineId);
+
+ Assert.True(nodeResult.IsOk, $"failed to get node due to {nodeResult.ErrorV}");
+ var node = nodeResult.OkV!.First();
+ node = await _nodeApi.WaitWhile(node.MachineId, n => n.State == "init" || n.State == "setup");
+
+ var r = await _nodeApi.Patch(node.MachineId);
+ Assert.True(r.Result);
+
+ var rr = await _nodeApi.Update(node.MachineId, false);
+
+ var d = await _nodeApi.Delete(node.MachineId);
+ Assert.True(d.Result);
+
+ var deletePool = await _poolApi.Delete(pool.Name);
+ Assert.True(deletePool.Result);
+ }
+
}
}
diff --git a/src/ApiService/FunctionalTests/TestPool.cs b/src/ApiService/FunctionalTests/TestPool.cs
index 56fb7668d..01562a3e1 100644
--- a/src/ApiService/FunctionalTests/TestPool.cs
+++ b/src/ApiService/FunctionalTests/TestPool.cs
@@ -19,7 +19,7 @@ namespace FunctionalTests {
[Fact]
async Task GetNonExistentPool() {
- var p = await _poolApi.Get(poolName: Guid.NewGuid().ToString());
+ var p = await _poolApi.Get(name: Guid.NewGuid().ToString());
Assert.True(p.ErrorV!.UnableToFindPoolError);
}
diff --git a/src/ApiService/FunctionalTests/TestProxy.cs b/src/ApiService/FunctionalTests/TestProxy.cs
index a2056a20f..e24a6f7ce 100644
--- a/src/ApiService/FunctionalTests/TestProxy.cs
+++ b/src/ApiService/FunctionalTests/TestProxy.cs
@@ -37,16 +37,7 @@ namespace FunctionalTests {
[Fact]
public async Task CreateResetDelete() {
- var newPoolId = Guid.NewGuid().ToString();
- var newPoolName = PoolApi.TestPoolPrefix + newPoolId;
- var newPool = await _poolApi.Create(newPoolName, "linux");
-
- Assert.True(newPool.IsOk, $"failed to create new pool: {newPool.ErrorV}");
-
- var newScalesetResult = await _scalesetApi.Create(newPool.OkV!.Name, 2);
-
- Assert.True(newScalesetResult.IsOk, $"failed to crate new scaleset: {newScalesetResult.ErrorV}");
- var newScaleset = newScalesetResult.OkV!;
+ var (newPool, newScaleset) = await Helpers.CreatePoolAndScaleset(_poolApi, _scalesetApi, "linux");
newScaleset = await _scalesetApi.WaitWhile(newScaleset.ScalesetId, sc => sc.State == "init" || sc.State == "setup");
@@ -81,12 +72,10 @@ namespace FunctionalTests {
_output.WriteLine($"deleted proxy");
- var deletePool = await _poolApi.Delete(newPoolName);
+ var deletePool = await _poolApi.Delete(newPool.Name);
Assert.True(deletePool.Result);
- _output.WriteLine($"deleted pool {newPoolName}");
+ _output.WriteLine($"deleted pool {newPool.Name}");
}
-
-
}
}
diff --git a/src/ApiService/FunctionalTests/TestScaleset.cs b/src/ApiService/FunctionalTests/TestScaleset.cs
index 4f3cf3b0d..fd700798f 100644
--- a/src/ApiService/FunctionalTests/TestScaleset.cs
+++ b/src/ApiService/FunctionalTests/TestScaleset.cs
@@ -34,18 +34,11 @@ namespace FunctionalTests {
}
}
- [Fact]
- public async Task CreateAndDelete() {
- var newPoolId = Guid.NewGuid().ToString();
- var newPoolName = PoolApi.TestPoolPrefix + newPoolId;
- var newPool = await _poolApi.Create(newPoolName, "linux");
+ public async Task CreateAndDelete(string os) {
+ var (newPool, newScaleset) = await Helpers.CreatePoolAndScaleset(_poolApi, _scalesetApi, os);
- Assert.True(newPool.IsOk, $"failed to create new pool: {newPool.ErrorV}");
-
- var newScalesetResult = await _scalesetApi.Create(newPool.OkV!.Name, 2);
-
- Assert.True(newScalesetResult.IsOk, $"failed to crate new scaleset: {newScalesetResult.ErrorV}");
- var newScaleset = newScalesetResult.OkV!;
+ var newScalesetResultAgain = await _scalesetApi.Create(newPool.Name, 2);
+ var newScalesetResultAgainAgain = await _scalesetApi.Create(newPool.Name, 5);
try {
_output.WriteLine($"New scale set info id: {newScaleset.ScalesetId}, pool: {newScaleset.PoolName}, state: {newScaleset.State}, error: {newScaleset.Error}");
@@ -56,7 +49,7 @@ namespace FunctionalTests {
var poolsCreated = await _poolApi.Get();
Assert.True(poolsCreated.IsOk, $"failed to get pools: {poolsCreated.ErrorV}");
- var newPools = poolsCreated.OkV!.Where(p => p.Name == newPoolName);
+ var newPools = poolsCreated.OkV!.Where(p => p.Name == newPool.Name);
var newScalesets = scalesetsCreated.OkV!.Where(sc => sc.ScalesetId == newScaleset.ScalesetId);
Assert.True(newPools.Count() == 1);
@@ -94,31 +87,43 @@ namespace FunctionalTests {
}
} finally {
var preDeleteScalesets = await _scalesetApi.Get();
- var deletedPoolResult = await _poolApi.Delete(newPoolName);
+ var deletedPoolResult = await _poolApi.Delete(newPool.Name);
Assert.True(preDeleteScalesets.IsOk, $"failed to get pre-deleted scalesets due to: {preDeleteScalesets.ErrorV}");
- var preDelete = preDeleteScalesets.OkV!.Where(sc => sc.PoolName == newPoolName);
- Assert.True(preDelete.Count() == 1);
+ var preDelete = preDeleteScalesets.OkV!.Where(sc => sc.PoolName == newPool.Name);
+ Assert.True(preDelete.Count() == 3);
Result, Error> deletedPool;
do {
await Task.Delay(TimeSpan.FromSeconds(10.0));
- deletedPool = await _poolApi.Get(newPoolName);
+ deletedPool = await _poolApi.Get(newPool.Name);
} while (deletedPool.IsOk);
Assert.True(deletedPool.ErrorV!.UnableToFindPoolError);
var postDeleteScalesets = await _scalesetApi.Get();
Assert.True(postDeleteScalesets.IsOk, $"failed to get scalesets after finishing pool deletion due to {postDeleteScalesets.ErrorV}");
- _output.WriteLine($"Pool is deleted {newPoolName}");
+ _output.WriteLine($"Pool is deleted {newPool.Name}");
- var postDelete = postDeleteScalesets.OkV!.Where(sc => sc.PoolName == newPoolName);
+ var postDelete = postDeleteScalesets.OkV!.Where(sc => sc.PoolName == newPool.Name);
Assert.False(postDelete.Any());
var patch1 = await _scalesetApi.Patch(newScaleset.ScalesetId, 1);
Assert.False(patch1.IsOk);
Assert.True(patch1.ErrorV!.UnableToFindScalesetError);
}
return;
+
+ }
+
+
+ [Fact]
+ public async Task CreateAndDeleteLinux() {
+ await CreateAndDelete("linux");
+ }
+
+ [Fact]
+ public async Task CreateAndDeleteWindows() {
+ await CreateAndDelete("windows");
}
}
}
diff --git a/src/ApiService/IntegrationTests/packages.lock.json b/src/ApiService/IntegrationTests/packages.lock.json
index ba79ae0f3..4e78e7fd1 100644
--- a/src/ApiService/IntegrationTests/packages.lock.json
+++ b/src/ApiService/IntegrationTests/packages.lock.json
@@ -103,11 +103,11 @@
},
"Azure.ResourceManager.Compute": {
"type": "Transitive",
- "resolved": "1.0.0",
- "contentHash": "dmDhokNFcyreIYZMkha8OsLmch0hW/sdOA2nxN4MPVd8KJgGWB8DxCZWwG7qhh59RInKtmWOP8BnBS5mN+W5wQ==",
+ "resolved": "1.0.0-beta.8",
+ "contentHash": "rYYjjmEdmcOa8O4UgO/bdJ/qQclNZjuHdalxRJ0AhUHCORcM1f1BbIKR9CoN83IpfuEE+X+n5XY9QZcKvfrGVA==",
"dependencies": {
- "Azure.Core": "1.25.0",
- "Azure.ResourceManager": "1.2.0",
+ "Azure.Core": "1.24.0",
+ "Azure.ResourceManager": "1.0.0",
"System.Text.Json": "4.7.2"
}
},
@@ -2153,7 +2153,7 @@
"Azure.Identity": "1.6.0",
"Azure.Messaging.EventGrid": "4.10.0",
"Azure.ResourceManager": "1.3.1",
- "Azure.ResourceManager.Compute": "1.0.0",
+ "Azure.ResourceManager.Compute": "[1.0.0-beta.8, )",
"Azure.ResourceManager.Monitor": "1.0.0-beta.2",
"Azure.ResourceManager.Network": "1.0.0",
"Azure.ResourceManager.Resources": "1.3.0",
diff --git a/src/ApiService/Tests/packages.lock.json b/src/ApiService/Tests/packages.lock.json
index 4676b47a2..2cc8b530c 100644
--- a/src/ApiService/Tests/packages.lock.json
+++ b/src/ApiService/Tests/packages.lock.json
@@ -131,11 +131,11 @@
},
"Azure.ResourceManager.Compute": {
"type": "Transitive",
- "resolved": "1.0.0",
- "contentHash": "dmDhokNFcyreIYZMkha8OsLmch0hW/sdOA2nxN4MPVd8KJgGWB8DxCZWwG7qhh59RInKtmWOP8BnBS5mN+W5wQ==",
+ "resolved": "1.0.0-beta.8",
+ "contentHash": "rYYjjmEdmcOa8O4UgO/bdJ/qQclNZjuHdalxRJ0AhUHCORcM1f1BbIKR9CoN83IpfuEE+X+n5XY9QZcKvfrGVA==",
"dependencies": {
- "Azure.Core": "1.25.0",
- "Azure.ResourceManager": "1.2.0",
+ "Azure.Core": "1.24.0",
+ "Azure.ResourceManager": "1.0.0",
"System.Text.Json": "4.7.2"
}
},
@@ -2297,7 +2297,7 @@
"Azure.Identity": "1.6.0",
"Azure.Messaging.EventGrid": "4.10.0",
"Azure.ResourceManager": "1.3.1",
- "Azure.ResourceManager.Compute": "1.0.0",
+ "Azure.ResourceManager.Compute": "[1.0.0-beta.8, )",
"Azure.ResourceManager.Monitor": "1.0.0-beta.2",
"Azure.ResourceManager.Network": "1.0.0",
"Azure.ResourceManager.Resources": "1.3.0",