public async Async.Task <OneFuzzResult <VirtualMachineScaleSetVmResource> > GetInstanceVm(Guid name, Guid vmId) { _log.Info($"get instance ID for scaleset node: {name}:{vmId}"); var scaleSet = GetVmssResource(name); try { await foreach (var vm in scaleSet.GetVirtualMachineScaleSetVms().AsAsyncEnumerable()) { var response = await vm.GetAsync(); if (!response.Value.HasData) { return(OneFuzzResult <VirtualMachineScaleSetVmResource> .Error(ErrorCode.UNABLE_TO_FIND, $"failed to get vm data")); } if (response.Value.Data.VmId == vmId.ToString()) { return(OneFuzzResult <VirtualMachineScaleSetVmResource> .Ok(response)); } } } catch (Exception ex) when(ex is RequestFailedException || ex is CloudException) { _log.Exception(ex, $"unable to find vm instance: {name}:{vmId}"); return(OneFuzzResult <VirtualMachineScaleSetVmResource> .Error(ErrorCode.UNABLE_TO_FIND, $"unable to find vm instance: {name}:{vmId}")); } return(OneFuzzResult <VirtualMachineScaleSetVmResource> .Error(ErrorCode.UNABLE_TO_FIND, $"unable to find scaleset machine: {name}:{vmId}")); }
public static async Async.Task <OneFuzzResult <T> > ParseRequest <T>(HttpRequestData req) { Exception?exception = null; try { var t = await req.ReadFromJsonAsync <T>(); if (t != null) { var validationContext = new ValidationContext(t); var validationResults = new List <ValidationResult>(); if (Validator.TryValidateObject(t, validationContext, validationResults, true)) { return(OneFuzzResult.Ok(t)); } else { return(new Error( Code: ErrorCode.INVALID_REQUEST, Errors: validationResults.Select(vr => vr.ToString()).ToArray())); } } } catch (Exception e) { exception = e; } if (exception != null) { return(OneFuzzResult <T> .Error(ConvertError(exception))); } return(OneFuzzResult <T> .Error( ErrorCode.INVALID_REQUEST, $"Failed to deserialize message into type: {typeof(T)} - {await req.ReadAsStringAsync()}" )); }
private async Async.Task <OneFuzzResult <DiagnosticSettingsResource> > SetupAutoScaleDiagnostics(string autoScaleResourceUri, string autoScaleResourceName, string logAnalyticsWorkspaceId) { var logSettings = new LogSettings(true) { Category = "allLogs", RetentionPolicy = new RetentionPolicy(true, 30) }; try { var parameters = new DiagnosticSettingsData { WorkspaceId = logAnalyticsWorkspaceId }; parameters.Logs.Add(logSettings); var diagnostics = await _context.Creds.GetResourceGroupResource().GetDiagnosticSettings().CreateOrUpdateAsync(WaitUntil.Completed, $"{autoScaleResourceName}-diagnostics", parameters); if (diagnostics != null && diagnostics.HasValue) { return(OneFuzzResult.Ok(diagnostics.Value)); } return(OneFuzzResult <DiagnosticSettingsResource> .Error( ErrorCode.UNABLE_TO_CREATE, $"The resulting diagnostics settings resource was null when attempting to create for {autoScaleResourceUri}" )); } catch (Exception ex) { _logTracer.Exception(ex); return(OneFuzzResult <DiagnosticSettingsResource> .Error( ErrorCode.UNABLE_TO_CREATE, $"unable to setup diagnostics for auto-scale resource: {autoScaleResourceUri}" )); } }
private async Async.Task <OneFuzzResult <AutoscaleSettingResource> > CreateAutoScaleResourceFor(Guid resourceId, string location, AutoscaleProfile profile) { _logTracer.Info($"Creating auto-scale resource for: {resourceId}"); var resourceGroup = _context.Creds.GetBaseResourceGroup(); var subscription = _context.Creds.GetSubscription(); var scalesetUri = $"/subscriptions/{subscription}/resourceGroups/{resourceGroup}/providers/Microsoft.Compute/virtualMachineScaleSets/{resourceId}"; var parameters = new AutoscaleSettingData(location, new[] { profile }) { TargetResourceId = scalesetUri, Enabled = true }; try { var autoScaleResource = await _context.Creds.GetResourceGroupResource().GetAutoscaleSettings() .CreateOrUpdateAsync(WaitUntil.Completed, Guid.NewGuid().ToString(), parameters); if (autoScaleResource != null && autoScaleResource.HasValue) { _logTracer.Info($"Successfully created auto scale resource {autoScaleResource.Id} for {resourceId}"); return(OneFuzzResult <AutoscaleSettingResource> .Ok(autoScaleResource.Value)); } return(OneFuzzResult <AutoscaleSettingResource> .Error( ErrorCode.UNABLE_TO_CREATE, $"Could not get auto scale resource value after creating for {resourceId}" )); } catch (Exception ex) { _logTracer.Exception(ex); return(OneFuzzResult <AutoscaleSettingResource> .Error( ErrorCode.UNABLE_TO_CREATE, $"unable to create auto scale resource for resource: {resourceId} with profile: {profile}")); } }
public async Task <OneFuzzResult <ProxyForward> > UpdateOrCreate(string region, Guid scalesetId, Guid machineId, int dstPort, int duration) { var privateIp = await _context.IpOperations.GetScalesetInstanceIp(scalesetId, machineId); if (privateIp == null) { return(OneFuzzResult <ProxyForward> .Error(ErrorCode.UNABLE_TO_PORT_FORWARD, "no private ip for node")); } var entries = await this.SearchForward(scalesetId : scalesetId, region : region, machineId : machineId, dstPort : dstPort).ToListAsync(); var firstEntry = entries.FirstOrDefault(); if (firstEntry != null) { var updated = firstEntry with { EndTime = DateTimeOffset.UtcNow + TimeSpan.FromHours(duration) }; await this.Update(updated); return(OneFuzzResult.Ok(updated)); } var exisiting = entries.Select(x => x.Port).ToHashSet(); foreach (var port in PORT_RANGES) { if (exisiting.Contains(port)) { continue; } var entry = new ProxyForward( Region: region, Port: port, ScalesetId: scalesetId, MachineId: machineId, DstIp: privateIp, DstPort: dstPort, EndTime: DateTimeOffset.UtcNow + TimeSpan.FromHours(duration), ProxyId: null ); var result = await Insert(entry); if (!result.IsOk) { _logTracer.Info($"port is already used {entry}"); } return(OneFuzzResult.Ok(entry)); } return(OneFuzzResult <ProxyForward> .Error(ErrorCode.UNABLE_TO_PORT_FORWARD, "all forward ports used")); }
public async Task <OneFuzzResult <bool> > AddExtensions(Vm vm, Dictionary <string, VirtualMachineExtensionData> extensions) { var status = new List <string>(); var toCreate = new List <KeyValuePair <string, VirtualMachineExtensionData> >(); foreach (var extensionConfig in extensions) { var extensionName = extensionConfig.Key; var extensionData = extensionConfig.Value; var extension = await GetExtension(vm.Name, extensionName); if (extension != null) { _logTracer.Info( $"vm extension state: {vm.Name} - {extensionName} - {extension.ProvisioningState}" ); status.Add(extension.ProvisioningState); } else { toCreate.Add(extensionConfig); } } if (toCreate.Any()) { foreach (var config in toCreate) { await CreateExtension(vm.Name, config.Key, config.Value); } } else { if (status.All(s => string.Equals(s, "Succeeded", StringComparison.Ordinal))) { return(OneFuzzResult <bool> .Ok(true)); } else if (status.Any(s => string.Equals(s, "Failed", StringComparison.Ordinal))) { return(OneFuzzResult <bool> .Error( ErrorCode.VM_CREATE_FAILED, "failed to launch extension" )); } else if (!(status.Contains("Creating") || status.Contains("Updating"))) { _logTracer.Error($"vm agent - unknown state {vm.Name}: {JsonConvert.SerializeObject(status)}"); } } return(OneFuzzResult <bool> .Ok(false)); }
public async Async.Task <OneFuzzResult <string> > GetInstanceId(Guid name, Guid vmId) { var vm = await GetInstanceVm(name, vmId); if (vm.IsOk) { return(OneFuzzResult <string> .Ok(vm.OkV !.Data.InstanceId)); } else { return(OneFuzzResult <string> .Error(vm.ErrorV)); } }
public async Async.Task <OneFuzzResult <VirtualMachineScaleSetData> > CheckCanUpdate(Guid name) { var vmss = await GetVmss(name); if (vmss is null) { return(OneFuzzResult <VirtualMachineScaleSetData> .Error(ErrorCode.UNABLE_TO_UPDATE, $"vmss not found: {name}")); } if (vmss.ProvisioningState == "Updating") { return(OneFuzzResult <VirtualMachineScaleSetData> .Error(ErrorCode.UNABLE_TO_UPDATE, $"vmss is in updating state: {name}")); } return(OneFuzzResult <VirtualMachineScaleSetData> .Ok(vmss)); }
public async Async.Task <OneFuzzResult <Pool> > GetByName(string poolName) { var pools = QueryAsync(filter: $"PartitionKey eq '{poolName}'"); if (pools == null || await pools.CountAsync() == 0) { return(OneFuzzResult <Pool> .Error(ErrorCode.INVALID_REQUEST, "unable to find pool")); } if (await pools.CountAsync() != 1) { return(OneFuzzResult <Pool> .Error(ErrorCode.INVALID_REQUEST, "error identifying pool")); } return(OneFuzzResult <Pool> .Ok(await pools.SingleAsync())); }
public async Task <OneFuzzResult <bool> > AddSshPublicKey(Node node, string publicKey) { if (publicKey == null) { throw new ArgumentNullException(nameof(publicKey)); } if (node.ScalesetId == null) { return(OneFuzzResult <bool> .Error(ErrorCode.INVALID_REQUEST, "only able to add ssh keys to scaleset nodes")); } var key = publicKey.EndsWith('\n') ? publicKey : $"{publicKey}\n"; await SendMessage(node, new NodeCommand { AddSshKey = new NodeCommandAddSshKey(key) }); return(OneFuzzResult.Ok <bool>(true)); }
public async Async.Task <OneFuzzResult <Pool> > GetByName(PoolName poolName) { var pools = QueryAsync(Query.PartitionKey(poolName.String)); var result = await pools.ToListAsync(); if (result.Count == 0) { return(OneFuzzResult <Pool> .Error(ErrorCode.INVALID_REQUEST, "unable to find pool")); } if (result.Count != 1) { return(OneFuzzResult <Pool> .Error(ErrorCode.INVALID_REQUEST, "error identifying pool")); } return(OneFuzzResult <Pool> .Ok(result.Single())); }
public async Async.Task <OneFuzzResult <Pool> > GetById(Guid poolId) { var pools = QueryAsync(Query.RowKey(poolId.ToString())); var result = await pools.ToListAsync(); if (result.Count == 0) { return(OneFuzzResult <Pool> .Error(ErrorCode.INVALID_REQUEST, "unable to find pool")); } if (result.Count != 1) { return(OneFuzzResult <Pool> .Error(ErrorCode.INVALID_REQUEST, "error identifying pool")); } return(OneFuzzResult <Pool> .Ok(result.Single())); }
public static async Async.Task <OneFuzzResult <T> > ParseUri <T>(HttpRequestData req) { var query = System.Web.HttpUtility.ParseQueryString(req.Url.Query); var doc = new JsonObject(); foreach (var key in query.AllKeys.WhereNotNull()) { doc[key] = JsonValue.Create(query[key]); } try { var result = doc.Deserialize <T>(EntityConverter.GetJsonSerializerOptions()); return(result switch { null => OneFuzzResult <T> .Error( ErrorCode.INVALID_REQUEST, $"Failed to deserialize message into type: {typeof(T)} - {await req.ReadAsStringAsync()}" ), var r => OneFuzzResult <T> .Ok(r), }); } catch (JsonException exception) {
static OneFuzzResult <Scaleset> TrySetIdentity(Scaleset scaleset, VirtualMachineScaleSetData vmss) { if (scaleset.ClientObjectId is null) { return(OneFuzzResult.Ok(scaleset)); } if (vmss.Identity is not null && vmss.Identity.UserAssignedIdentities is not null) { if (vmss.Identity.UserAssignedIdentities.Count != 1) { return(OneFuzzResult <Scaleset> .Error(ErrorCode.VM_CREATE_FAILED, "The scaleset is expected to have exactly 1 user assigned identity")); } var principalId = vmss.Identity.UserAssignedIdentities.First().Value.PrincipalId; if (principalId is null) { return(OneFuzzResult <Scaleset> .Error(ErrorCode.VM_CREATE_FAILED, "The scaleset principal ID is null")); } return(OneFuzzResult <Scaleset> .Ok(scaleset with { ClientObjectId = principalId })); }
public OneFuzzResult <AutoscaleSettingResource?> GetAutoscaleSettings(Guid vmss) { _logTracer.Info($"Checking scaleset {vmss} for existing auto scale resource"); var monitorManagementClient = _context.LogAnalytics.GetMonitorManagementClient(); var resourceGroup = _context.Creds.GetBaseResourceGroup(); try { var autoscale = _context.Creds.GetResourceGroupResource().GetAutoscaleSettings() .ToEnumerable() .Where(autoScale => autoScale.Data.TargetResourceId.EndsWith(vmss.ToString())) .FirstOrDefault(); if (autoscale != null) { _logTracer.Info($"Found autoscale settings for {vmss}"); return(OneFuzzResult.Ok <AutoscaleSettingResource?>(autoscale)); } } catch (Exception ex) { _logTracer.Exception(ex); return(OneFuzzResult <AutoscaleSettingResource?> .Error(ErrorCode.INVALID_CONFIGURATION, $"Failed to check if scaleset {vmss} already has an autoscale resource")); } return(OneFuzzResult.Ok <AutoscaleSettingResource?>(null)); }
public static async Async.Task <OneFuzzResult <T> > ParseRequest <T>(HttpRequestData req) { Exception?exception = null; try { var t = await req.ReadFromJsonAsync <T>(); if (t != null) { return(OneFuzzResult <T> .Ok(t)); } } catch (Exception e) { exception = e; } if (exception != null) { return(OneFuzzResult <T> .Error(ConvertError(exception))); } return(OneFuzzResult <T> .Error( ErrorCode.INVALID_REQUEST, $"Failed to deserialize message into type: {typeof(T)} - {await req.ReadAsStringAsync()}" )); }
public async Task <OneFuzzResult <Os> > GetOs(string region, string image) { string?name = null; try { var parsed = _context.Creds.ParseResourceId(image); parsed = await _context.Creds.GetData(parsed); if (string.Equals(parsed.Id.ResourceType, "galleries", StringComparison.OrdinalIgnoreCase)) { try { // This is not _exactly_ the same as the python code // because in C# we don't have access to child_name_1 var gallery = await _context.Creds.GetResourceGroupResource().GetGalleries().GetAsync( parsed.Data.Name ); var galleryImage = gallery.Value.GetGalleryImages() .ToEnumerable() .Where(galleryImage => string.Equals(galleryImage.Id, parsed.Id, StringComparison.OrdinalIgnoreCase)) .First(); galleryImage = await galleryImage.GetAsync(); name = galleryImage.Data?.OSType?.ToString().ToLowerInvariant() !; } catch (Exception ex) when( ex is RequestFailedException || ex is NullReferenceException ) { return(OneFuzzResult <Os> .Error( ErrorCode.INVALID_IMAGE, ex.ToString() )); } } else { try { name = (await _context.Creds.GetResourceGroupResource().GetImages().GetAsync( parsed.Data.Name )).Value.Data.StorageProfile.OSDisk.OSType.ToString().ToLowerInvariant(); } catch (Exception ex) when( ex is RequestFailedException || ex is NullReferenceException ) { return(OneFuzzResult <Os> .Error( ErrorCode.INVALID_IMAGE, ex.ToString() )); } } } catch (FormatException) { var imageInfo = IImageOperations.GetImageInfo(image); try { var subscription = await _context.Creds.ArmClient.GetDefaultSubscriptionAsync(); string version; if (string.Equals(imageInfo.Version, "latest", StringComparison.Ordinal)) { version = (await subscription.GetVirtualMachineImagesAsync( region, imageInfo.Publisher, imageInfo.Offer, imageInfo.Sku, top: 1 ).FirstAsync()).Name; } else { version = imageInfo.Version; } name = (await subscription.GetVirtualMachineImageAsync( region, imageInfo.Publisher, imageInfo.Offer, imageInfo.Sku , version )).Value.OSDiskImageOperatingSystem.ToString().ToLower(); } catch (RequestFailedException ex) { return(OneFuzzResult <Os> .Error( ErrorCode.INVALID_IMAGE, ex.ToString() )); } } if (name != null) { name = string.Concat(name[0].ToString().ToUpper(), name.AsSpan(1)); if (Enum.TryParse(name, out Os os)) { return(OneFuzzResult <Os> .Ok(os)); } } return(OneFuzzResult <Os> .Error( ErrorCode.INVALID_IMAGE, $"Unexpected image os type: {name}" )); }