Exemplo n.º 1
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post",
                         Route = "subscriptions/{SUBSCRIPTIONID}/resourceGroups/{RESOURCEGROUPNAME}/providers/Microsoft.DevTestLab/labs/{LABNAME}/virtualmachines/{VIRTUALMACHINENAME}")] HttpRequest req,
            string subscriptionId,
            string resourceGroupName,
            string labName,
            string virtualMachineName,
            ILogger log)
        {
            log.LogInformation($"Function to apply the Windows Update artifact on VM {virtualMachineName} in lab {labName} in subscription {subscriptionId} started processing at {DateTime.Now}");

            // Authentication helper, keeps track of the access token and encapsulates authentication into Azure & DTL Client
            var authenticationHelper = new Authentication(log);
            await authenticationHelper.RetrieveAccessTokenAsync();

            // login to the DevTest Labs APIs
            var dtlClient         = authenticationHelper.LoginToDevTestLabsAPIs(subscriptionId);
            var azureClient       = authenticationHelper.LoginToAzure(subscriptionId);
            var devTestLabsHelper = new DevTestLabs(azureClient, dtlClient, log);

            // Get the lab's resource id (which also confirms the lab exists)
            string labResourceId = await devTestLabsHelper.GetDevTestLabResourceId(resourceGroupName, labName);

            // Get the virtual machine
            LabVirtualMachine vm = await devTestLabsHelper.GetDevTestLabVirtualMachine(resourceGroupName, labName, virtualMachineName);

            // Let's make sure the VM is OK to apply artifacts


            if (await devTestLabsHelper.IsVirtualMachineReadyForArtifacts(vm))
            {
                var artifactRequest = new ApplyArtifactsRequest(new List <ArtifactInstallProperties> {
                    new ArtifactInstallProperties($"{labResourceId}/artifactSources/public repo/artifacts/windows-install-windows-updates")
                });

                // We fire off the request to apply artifacts, but we don't wait until it's complete before wrapping up the function
                // If we wanted to wait, we would use "dtlClient.VirtualMachines.ApplyArtifactsAsync()" instead
                dtlClient.VirtualMachines.BeginApplyArtifacts(resourceGroupName, labName, virtualMachineName, artifactRequest);
            }
            else
            {
                log.LogError($"The VM must be running to apply artifacts!  ResourceGroupName '{resourceGroupName}', LabName '{labName}', VM '{virtualMachineName}'");

                return(new ContentResult()
                {
                    Content = Content.GetHtmlResponse(Content.responseType.VirtualMachineNotRunning, false),
                    ContentType = "text/html",
                    StatusCode = 200
                });
            }

            return(new ContentResult()
            {
                Content = Content.GetHtmlResponse(Content.responseType.VirtualMachineSuccess, true),
                ContentType = "text/html",
                StatusCode = 200
            });
        }
Exemplo n.º 2
0
        public async Task <bool> IsVirtualMachineReadyForArtifacts(LabVirtualMachine vm)
        {
            // 1st, we have to first check the lab machine provisioning state (this ensures that the VM isn't creating, deleting, applying artifacts, etc)
            if (vm.ProvisioningState == "Succeeded")
            {
                // 2nd, we need to ensure that the underlying compute has provisioning state == succeeded and power state == running
                string powerState, provisioningState;

                if (vm.ComputeVm != null)
                {
                    // If we already have the Compute VM, let's use it directly rather than query Azure again
                    powerState = (from s in vm.ComputeVm.Statuses
                                  where s.Code.Contains("PowerState/")
                                  select s).FirstOrDefault()?.Code.Replace("PowerState/", "").ToLower();
                    provisioningState = (from s in vm.ComputeVm.Statuses
                                         where s.Code.Contains("ProvisioningState/")
                                         select s).FirstOrDefault()?.Code.Replace("ProvisioningState/", "").ToLower();
                }
                else
                {
                    // We don't have the compute VM, so we need the underlying resource status to continue
                    var computeVm = await azureClient.VirtualMachines.GetByIdAsync(vm.ComputeId);

                    powerState        = computeVm.PowerState?.Value.Replace("PowerState/", "").ToLower();
                    provisioningState = computeVm.ProvisioningState.Replace("ProvisioningState/", "").ToLower();
                }

                if (powerState == "running" && provisioningState == "succeeded")
                {
                    return(true);
                }
                else
                {
                    log.LogInformation($"  .. Virtual machine '{vm.Name}' has PowerState '{powerState}' and ProvisioningState '{provisioningState}', cannot apply artifacts ");
                    return(false);
                }
            }
            else
            {
                log.LogInformation($"  .. Virtual machine '{vm.Name}' has DTL ProvisioningState '{vm.ProvisioningState}', cannot apply artifacts ");
                return(false);
            }
        }
Exemplo n.º 3
0
 /// <summary>
 /// Create virtual machines in a Lab. This operation can take a while to
 /// complete.
 /// </summary>
 /// <param name='operations'>
 /// The operations group for this extension method.
 /// </param>
 /// <param name='resourceGroupName'>
 /// The name of the resource group.
 /// </param>
 /// <param name='name'>
 /// The name of the lab.
 /// </param>
 /// <param name='labVirtualMachine'>
 /// </param>
 /// <param name='cancellationToken'>
 /// The cancellation token.
 /// </param>
 public static async Task BeginCreateEnvironmentAsync(this ILabOperations operations, string resourceGroupName, string name, LabVirtualMachine labVirtualMachine, CancellationToken cancellationToken = default(CancellationToken))
 {
     await operations.BeginCreateEnvironmentWithHttpMessagesAsync(resourceGroupName, name, labVirtualMachine, null, cancellationToken).ConfigureAwait(false);
 }
Exemplo n.º 4
0
 /// <summary>
 /// Create virtual machines in a Lab. This operation can take a while to
 /// complete.
 /// </summary>
 /// <param name='operations'>
 /// The operations group for this extension method.
 /// </param>
 /// <param name='resourceGroupName'>
 /// The name of the resource group.
 /// </param>
 /// <param name='name'>
 /// The name of the lab.
 /// </param>
 /// <param name='labVirtualMachine'>
 /// </param>
 public static void BeginCreateEnvironment(this ILabOperations operations, string resourceGroupName, string name, LabVirtualMachine labVirtualMachine)
 {
     Task.Factory.StartNew(s => ((ILabOperations)s).BeginCreateEnvironmentAsync(resourceGroupName, name, labVirtualMachine), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult();
 }
 /// <summary>
 /// Modify properties of virtual machines.
 /// </summary>
 /// <param name='operations'>
 /// The operations group for this extension method.
 /// </param>
 /// <param name='resourceGroupName'>
 /// The name of the resource group.
 /// </param>
 /// <param name='labName'>
 /// The name of the lab.
 /// </param>
 /// <param name='name'>
 /// The name of the virtual Machine.
 /// </param>
 /// <param name='labVirtualMachine'>
 /// </param>
 /// <param name='cancellationToken'>
 /// The cancellation token.
 /// </param>
 public static async Task <LabVirtualMachine> PatchResourceAsync(this IVirtualMachineOperations operations, string resourceGroupName, string labName, string name, LabVirtualMachine labVirtualMachine, CancellationToken cancellationToken = default(CancellationToken))
 {
     using (var _result = await operations.PatchResourceWithHttpMessagesAsync(resourceGroupName, labName, name, labVirtualMachine, null, cancellationToken).ConfigureAwait(false))
     {
         return(_result.Body);
     }
 }
 /// <summary>
 /// Modify properties of virtual machines.
 /// </summary>
 /// <param name='operations'>
 /// The operations group for this extension method.
 /// </param>
 /// <param name='resourceGroupName'>
 /// The name of the resource group.
 /// </param>
 /// <param name='labName'>
 /// The name of the lab.
 /// </param>
 /// <param name='name'>
 /// The name of the virtual Machine.
 /// </param>
 /// <param name='labVirtualMachine'>
 /// </param>
 public static LabVirtualMachine PatchResource(this IVirtualMachineOperations operations, string resourceGroupName, string labName, string name, LabVirtualMachine labVirtualMachine)
 {
     return(Task.Factory.StartNew(s => ((IVirtualMachineOperations)s).PatchResourceAsync(resourceGroupName, labName, name, labVirtualMachine), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult());
 }