/// <summary> /// Find the virtual machines in the group and determine what ones need to have /// the powerstate modified /// </summary> /// <param name="rg"></param> private void manageVirtualMachines(IResourceGroup rg) { // get a list of the virtual machines in the group IEnumerable <IVirtualMachine> virtualMachines = azure.VirtualMachines.ListByResourceGroup(rg.Name); // check the beginning of the name of hte resource group // if it starts with MC_ then it will be a managed cluster and Reaper should not deal // with the virtual machines directly if (rg.Name.ToLower().StartsWith("mc_")) { _logger.Information("Not managing Virtual Machines in managed AKS cluster: {0}", rg.Name); return; } if (virtualMachines.Count() == 0) { _logger.Information("No Virtual Machines in group: {0}", rg.Name); return; } _logger.Information("Analysing Virtual Machines: {0}", virtualMachines.Count().ToString()); // Determine if VMs are to be managed, return if they are not bool manage_vms = Convert.ToBoolean(settings.First(s => s.name == "manage_vms").value); if (!manage_vms) { _logger.Information("Reaper is not set to manage virtual machines, please check your settings"); return; } foreach (IVirtualMachine vm in virtualMachines) { // get the powerstate of the vm string powerstate = vm.PowerState.ToString(); // Create a powerschedule object to determine if the machine should be running or not PowerSchedule powerSchedule = new PowerSchedule( settings, timezones, _logger, timeNowUtc, rg.Tags, vm.Tags, powerstate, vm.RegionName ); powerSchedule.Process(); // start or stop the resource based on the results from the powerschedule if (powerSchedule.StartResource()) { powerStats.StartResource("vm", vm.Name); _logger.Information("[{0}] Starting virtual machine: {1}", rg.Name, vm.Name); vm.StartAsync(); } if (powerSchedule.StopResource()) { powerStats.StopResource("vm", vm.Name); _logger.Information("[{0}] Stopping virtual machine: {1}", rg.Name, vm.Name); vm.DeallocateAsync(); } } }
/// <summary> /// Find the Kubernetes clusters in the specified resource group and determine if they need to be /// left alone, shutdown or startedup /// </summary> /// <param name="rgName">Name of hte resource group to look for clusters in</param> private void manageK8sClusters(IResourceGroup rg) { // determine if any kubernetes clusters exist in the group IEnumerable <IKubernetesCluster> clusters = azure.KubernetesClusters.ListByResourceGroup(rg.Name); if (clusters.Count() == 0) { _logger.Information("No AKS clusters in group: {0}", rg.Name); } else { _logger.Information("Analysing AKS Clusters: {0}", clusters.Count().ToString()); // iterate around the clusters foreach (IKubernetesCluster cluster in clusters) { string operation = String.Empty; string powerState = cluster.Inner.PowerState.Code.Value; // Determine if the cluster should be running or not PowerSchedule powerSchedule = new PowerSchedule( settings, timezones, _logger, timeNowUtc, rg.Tags, cluster.Tags, powerState, cluster.RegionName ); powerSchedule.Process(); // use the powerschedule information to determine if the resource should be running if (powerSchedule.StartResource()) { powerStats.StartResource("aks", cluster.Name); operation = "start"; } if (powerSchedule.StopResource()) { powerStats.StopResource("aks", cluster.Name); operation = "stop"; } if (!String.IsNullOrEmpty(operation)) { // build up the URL object[] replacements = { cluster.Manager.RestClient.BaseUri, cluster.Manager.SubscriptionId, rg.Name, cluster.Name, operation }; string url = String.Format("{0}subscriptions/{1}/resourceGroups/{2}/providers/Microsoft.ContainerService/managedClusters/{3}/{4}?api-version=2021-05-01", replacements); _logger.Information(url); // Create a new HttpClient top HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url); CancellationToken cancellationToken = new CancellationToken(); HttpClient httpClient = new HttpClient(); cluster.Manager.RestClient.Credentials.ProcessHttpRequestAsync(request, cancellationToken).GetAwaiter().GetResult(); HttpResponseMessage response = httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).GetAwaiter().GetResult(); _logger.Information(response.Content.ReadAsStringAsync().Result); } } } }