Esempio n. 1
0
        public static async Task <ResourceCleanerOperation> DeleteStorageAccounts()
        {
            var cleanOperation = new ResourceCleanerOperation();

            cleanOperation.ResourceType = "Storage Accounts";
            using (var httpClient = new CustomHttpClient(_logger))
            {
                var accessToken = await Utility.GetServicePrincipalAccessToken(_clientId, _clientSecret);

                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
                string requestUri = $"https://management.azure.com/subscriptions/{_subscription}/resourceGroups/Default-Storage-CentralUS/providers/Microsoft.Storage/storageAccounts?api-version=2017-10-01";
                var    request    = new HttpRequestMessage(HttpMethod.Get, new Uri(requestUri));
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                var response = await httpClient.SendAsync("GetStorageAccounts", request);

                var result = await response.Content.ReadAsStringAsync();

                var json = JObject.Parse(result);

                cleanOperation.Total = json["value"].Select(i => (JObject)i).Count();

                var expiredStorageAccounts = json["value"].Select(i => (JObject)i)
                                             .Where(o => (DateTime.UtcNow - DateTime.Parse(o["properties"]["creationTime"].Value <string>())) >= TimeSpan.FromHours(_resourceMaxLivingTimeInHours))
                                             .Select(i => i["id"].Value <string>());

                foreach (var resourceId in expiredStorageAccounts)
                {
                    response = await httpClient.SendAsync("DeleteStorageAccounts", new HttpRequestMessage(HttpMethod.Delete, $"https://management.azure.com{resourceId}?api-version=2017-10-01"));

                    _logger.Info($"DELETE storageaccount: {resourceId.Split(new char[] { '/' }).Last()} StatusCode: {response.StatusCode}");
                    if (response.IsSuccessStatusCode)
                    {
                        cleanOperation.TotalScavenged += 1;
                    }
                    else
                    {
                        cleanOperation.TotalResourceDeletionFailures += 1;
                    }
                }
            }

            return(cleanOperation);
        }
Esempio n. 2
0
        public static async Task <ResourceCleanerOperation> DeleteSqlServers()
        {
            var cleanOperation = new ResourceCleanerOperation();

            cleanOperation.ResourceType = "SQL Server";
            var deleteSqlServer = new List <Uri>();

            var clientId     = Environment.GetEnvironmentVariable("AAD_ClientId");
            var clientSecret = Environment.GetEnvironmentVariable("AAD_ClientSecret");

            using (var httpClient = new CustomHttpClient(_logger))
            {
                var accessToken = await Utility.GetServicePrincipalAccessToken(clientId, clientSecret);

                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
                //list sql servers in the subscription
                var    subscription = Environment.GetEnvironmentVariable("CloudResourcesSubscriptionId");
                string requestUri   = $"https://management.azure.com/subscriptions/{subscription}/providers/Microsoft.Sql/servers?api-version=2015-05-01-preview";
                var    request      = new HttpRequestMessage(HttpMethod.Get, new Uri(requestUri));
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                var response = await httpClient.SendAsync("GetSqlServers", request);

                var result = await response.Content.ReadAsStringAsync();

                var json = JObject.Parse(result);
                var serverResourceUrls = json["value"].Select(i => (JObject)i).Select(i => i["id"].Value <string>()).Select(path => $"https://management.azure.com{path}");
                cleanOperation.Total = serverResourceUrls.Count();

                foreach (var url in serverResourceUrls)
                {
                    var getDatabasesUrl = $"{url}/databases?api-version=2017-10-01-preview";
                    request  = new HttpRequestMessage(HttpMethod.Get, getDatabasesUrl);
                    response = await httpClient.SendAsync("GetDatabases", request);

                    result = await response.Content.ReadAsStringAsync();

                    json = JObject.Parse(result);

                    var hostingDbCreationDateString = json["value"].Select(i => (JObject)i).Where(o => o["name"].Value <string>() == "master").Single()["properties"]["creationDate"].Value <string>();

                    if ((DateTime.UtcNow - DateTime.Parse(hostingDbCreationDateString)) >= TimeSpan.FromHours(_resourceMaxLivingTimeInHours))
                    {
                        request = new HttpRequestMessage(HttpMethod.Delete, $"{url}?api-version=2015-05-01-preview");
                        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                        response = await httpClient.SendAsync("DeleteSqlServers", request);

                        _logger.Info($"DELETE SqlServer: {url.Split(new char[] { '/' }).Last()} StatusCode: {response.StatusCode}");
                        if (response.IsSuccessStatusCode)
                        {
                            cleanOperation.TotalScavenged += 1;
                        }
                        else
                        {
                            cleanOperation.TotalResourceDeletionFailures += 1;
                        }
                    }
                }
            }

            return(cleanOperation);
        }
Esempio n. 3
0
        public static async Task <ResourceCleanerOperation> DeleteResourceGroups()
        {
            var operation = new ResourceCleanerOperation();

            operation.ResourceType = "ResourceGroups";

            var         config = new KustoConfiguration();
            IDataReader reader;

            using (var client = new KustoClientReader(config, config.KustoDatabase))
            {
                reader = await client.GetData("stampyvmssmgmt", config.KustoDatabase, Queries.GetCreatedServices());
            }

            var tableResult = new DataTable();

            tableResult.Load(reader);

            var expiredServices = new List <string>();

            foreach (DataRow row in tableResult.Rows)
            {
                var timestamp = DateTime.Parse(row["TimeStamp"].ToString());
                if ((DateTime.UtcNow - timestamp).TotalHours >= _resourceMaxLivingTimeInHours)
                {
                    expiredServices.Add(row["StampName"].ToString());
                    expiredServices.Add($"{row["StampName"].ToString()}geo");
                }
            }

            using (var httpClient = new CustomHttpClient(_logger))
            {
                var accessToken = await Utility.GetServicePrincipalAccessToken(_clientId, _clientSecret);

                string requestUri = $"https://management.azure.com/subscriptions/{_subscription}/resourcegroups?api-version=2018-05-01";
                var    request    = new HttpRequestMessage(HttpMethod.Get, new Uri(requestUri));
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

                var response = await httpClient.SendAsync("ListResourceGroups", request);

                if (response.IsSuccessStatusCode)
                {
                    var result = await response.Content.ReadAsStringAsync();

                    var json             = JObject.Parse(result);
                    var resourceGroups   = json["value"].Select(i => (JObject)i).Where(i => expiredServices.Contains(i.Value <string>("name")));
                    var resourceGroupIds = resourceGroups.Select(i => i.Value <string>("id"));
                    operation.Total = resourceGroupIds.Count();

                    var operations = new List <string>();

                    var operationStatusUrls = new Dictionary <string, string>();
                    foreach (var resourceId in resourceGroupIds)
                    {
                        requestUri = $"https://management.azure.com{resourceId}?api-version=2018-05-01";
                        response   = await httpClient.SendAsync("DeleteResourceGroups", new HttpRequestMessage(HttpMethod.Delete, requestUri));

                        if (response.IsSuccessStatusCode)
                        {
                            if (response.Headers.TryGetValues("Location", out IEnumerable <string> values))
                            {
                                operationStatusUrls.Add(resourceId, values.First());
                            }
                        }
                    }

                    while (operationStatusUrls.Count > 0)
                    {
                        await Task.Delay(20 * 1000);

                        var deletedResources = new List <string>();
                        foreach (var item in operationStatusUrls)
                        {
                            response = await httpClient.SendAsync("CheckingOperation", new HttpRequestMessage(HttpMethod.Get, item.Value));

                            _logger.Info($"DeleteOperationStatus for {item.Key} : {response.StatusCode}");
                            if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.NoContent)
                            {
                                operation.TotalScavenged += 1;
                                deletedResources.Add(item.Key);
                            }
                            else if ((int)response.StatusCode >= 500)
                            {
                                _logger.Error($"Failed to delete resourceGroup with Id: {item.Key}");
                                operation.TotalResourceDeletionFailures += 1;
                            }
                        }

                        foreach (var item in deletedResources)
                        {
                            operationStatusUrls.Remove(item);
                        }
                    }
                }
            }

            return(operation);
        }
Esempio n. 4
0
        public static async Task <ResourceCleanerOperation> DeleteCloudServices()
        {
            var cleanOperation = new ResourceCleanerOperation()
            {
                ResourceType = "Cloud Services"
            };
            var deleteRequestIds         = new List <string>();
            var handler                  = new HttpClientHandler();
            X509Certificate2 certificate = GetMyX509Certificate(Environment.GetEnvironmentVariable("RDFECertThumbprint"));

            if (certificate != null)
            {
                _logger.Info("Cert found");
            }
            handler.ClientCertificates.Add(certificate);
            handler.ClientCertificateOptions = ClientCertificateOption.Manual;
            handler.ServerCertificateCustomValidationCallback = (request, cert, chain, errors) =>
            {
                return(true);
            };

            Stream responseXmlDocument;

            using (var httpClient = new CustomHttpClient(_logger, handler))
            {
                string requestUri = $"https://management.core.windows.net/{_subscription}/services/hostedservices";
                var    request    = new HttpRequestMessage(HttpMethod.Get, new Uri(requestUri));
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
                request.Headers.Add("x-ms-version", "2012-03-01");
                var response = await httpClient.SendAsync("GetCloudServices", request);

                responseXmlDocument = await response.Content.ReadAsStreamAsync();

                var xmlDoc = new XmlDocument();
                xmlDoc.Load(responseXmlDocument);
                foreach (XmlNode item in xmlDoc.DocumentElement.ChildNodes)
                {
                    cleanOperation.Total += 1;
                    string   cloudServiceName       = item["ServiceName"].FirstChild.Value;
                    string   dateLastModifiedString = item["HostedServiceProperties"]["DateLastModified"].FirstChild.Value;
                    DateTime dateLastModified       = DateTime.Parse(dateLastModifiedString);

                    if (DateTime.UtcNow.Subtract(dateLastModified).TotalHours > _resourceMaxLivingTimeInHours)
                    {
                        requestUri = $"https://management.core.windows.net/{_subscription}/services/hostedservices/{cloudServiceName}?comp=media";
                        var deleteRequest = new HttpRequestMessage(HttpMethod.Delete, requestUri);
                        deleteRequest.Headers.Add("x-ms-version", "2013-08-01");
                        var deleteResponse = await httpClient.SendAsync(deleteRequest);

                        var operationRequestId = deleteResponse.Headers.GetValues("x-ms-request-id").First();
                        _logger.Info($"DELETE cloud service: {cloudServiceName} StatusCode:{deleteResponse.StatusCode} x-ms-requestid:{operationRequestId}");
                        if (deleteResponse.IsSuccessStatusCode)
                        {
                            cleanOperation.TotalScavenged += 1;
                        }
                        else
                        {
                            cleanOperation.TotalResourceDeletionFailures += 1;
                        }
                        deleteRequestIds.Add(operationRequestId);
                    }
                }

                foreach (string operationRequestId in deleteRequestIds)
                {
                    var checkOperation        = $"https://management.core.windows.net/{_subscription}/operations/{operationRequestId}";
                    var checkOperationRequest = new HttpRequestMessage(HttpMethod.Get, requestUri);
                    checkOperationRequest.Headers.Add("x-ms-version", "2013-08-01");
                    checkOperationRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
                    var checkOperationResponse = await httpClient.SendAsync(checkOperationRequest);

                    if (checkOperationResponse.IsSuccessStatusCode)
                    {
                        //check the response body for the status of the asynchronous operation
                        xmlDoc = new XmlDocument();
                        xmlDoc.Load(await checkOperationResponse.Content.ReadAsStreamAsync());
                        _logger.Info($"x-ms-requestid:{operationRequestId} StatusCode:{xmlDoc.DocumentElement["HttpStatusCode"].FirstChild.Value} Details:{xmlDoc.DocumentElement["Error"]["Code"].FirstChild.Value} {xmlDoc.DocumentElement["Error"]["Message"].FirstChild.Value}");
                    }
                }
            }

            return(cleanOperation);
        }