public HomeController(IOptions <AzureADSettings> settings, AzureResourceManagerUtil resourceManagerUtilty, ISubscriptionRepository subscriptionRepository, SignedInUserService signedInUserService) { azureADSettings = settings.Value; this.resourceManagerUtility = resourceManagerUtilty; this.subscriptionRepository = subscriptionRepository; this.signedInUserService = signedInUserService; }
public async Task <HttpResponseMessage> GetAllUserResourceGroupsBySubscription(string subscriptionId) { var json = await AzureResourceManagerUtil.GetUserResourceGroups(subscriptionId); var response = this.Request.CreateResponse(HttpStatusCode.OK); response.Content = json.ToStringContent(); return(response); }
public async Task <HttpResponseMessage> GetByCorrelationId(string subscriptionId, string correlationId) { var json = await AzureResourceManagerUtil.GetAuditLogs(subscriptionId, correlationId); var response = this.Request.CreateResponse(HttpStatusCode.OK); response.Content = json.ToStringContent(); return(response); }
public async Task <HttpResponseMessage> GetResourcesProvider(string subscriptionId) { var json = await AzureResourceManagerUtil.GetResourcesProvider(subscriptionId); var response = this.Request.CreateResponse(HttpStatusCode.OK); response.Content = new StringContent(json, Encoding.UTF8, "application/json"); return(response); }
public ActionResult Refresh() { try { // get all organizations and their respective subscription for a given tenant var orgs = AzureResourceManagerUtil.GetUserOrganizations(); Dictionary <Organization, List <Subscription> > dictionary = new Dictionary <Organization, List <Subscription> >(); foreach (var item in orgs) { if (!dictionary.ContainsKey(item)) { var subscriptions = AzureResourceManagerUtil.GetUserSubscriptions(item.Id); dictionary.Add(item, subscriptions); } } // check if these subscriptions are already added in the storage var repo = new EntityRepo <UserSubscription>(); var list = repo.Get(USER_SUBSCRIPTION_TABLE_PARTITION_KEY, null, ""); var existingSubscriptions = new Dictionary <string, string>(); foreach (var item in list) { existingSubscriptions.Add(item.SubscriptionId, item.SubscriptionId); } // list of new subscription to add var listOfUserSubscription = new List <UserSubscription>(); foreach (var subscriptions in dictionary.Values) { foreach (var subscription in subscriptions) { UserSubscription userSubscription = new UserSubscription(subscription.Id, subscription.OrganizationId); userSubscription.DisplayName = subscription.DisplayName; // if the subscription is not already in the storage add them // otherwise the one in the storage should have latest info if (!existingSubscriptions.ContainsKey(userSubscription.SubscriptionId)) { listOfUserSubscription.Add(userSubscription); } } } // if one or more subscriptions are discovered, add them if (listOfUserSubscription.Count > 0) { repo.Insert(listOfUserSubscription); } return(Json(dictionary.ToList(), JsonRequestBehavior.AllowGet)); } catch (Exception exp) { Logger.Log("Subscription-Web-API", "Error", exp.Message, exp.ToString()); return(new HttpStatusCodeResult(500, exp.Message)); } }
public ActionResult RepairAccess([Bind(Include = "Id, OrganizationId")] Subscription subscription, string servicePrincipalObjectId) { if (ModelState.IsValid) { AzureResourceManagerUtil.RevokeRoleFromServicePrincipalOnSubscription(servicePrincipalObjectId, subscription.Id, subscription.OrganizationId); AzureResourceManagerUtil.GrantRoleToServicePrincipalOnSubscription(servicePrincipalObjectId, subscription.Id, subscription.OrganizationId); } return(RedirectToAction("Index", "Home")); }
public ActionResult RepairAccess([Bind(Include = "Id")] Subscription subscription) { if (ModelState.IsValid) { AzureResourceManagerUtil.RevokeRoleFromServicePrincipalOnSubscription(ConfigurationManager.AppSettings["ObjectId"], subscription.Id, ConfigurationManager.AppSettings["AADId"]); AzureResourceManagerUtil.GrantRoleToServicePrincipalOnSubscription(ConfigurationManager.AppSettings["ObjectId"], subscription.Id, ConfigurationManager.AppSettings["AADId"]); } return(RedirectToAction("Index", "Home")); }
public ActionResult Index() { HomeIndexViewModel model = null; if (ClaimsPrincipal.Current.Identity.IsAuthenticated) { model = new HomeIndexViewModel(); model.UserOrganizations = new Dictionary <string, Organization>(); model.UserSubscriptions = new Dictionary <string, Subscription>(); model.UserCanManageAccessForSubscriptions = new List <string>(); model.DisconnectedUserOrganizations = new List <string>(); var orgnaizations = AzureResourceManagerUtil.GetUserOrganizations(); foreach (Organization org in orgnaizations) { model.UserOrganizations.Add(org.Id, org); var subscriptions = AzureResourceManagerUtil.GetUserSubscriptions(org.Id); if (subscriptions != null) { foreach (var subscription in subscriptions) { Subscription s = db.Subscriptions.Find(subscription.Id); if (s != null) { subscription.IsConnected = true; subscription.ConnectedOn = s.ConnectedOn; subscription.ConnectedBy = s.ConnectedBy; subscription.AzureAccessNeedsToBeRepaired = AzureResourceManagerUtil.ServicePrincipalHasReadAccessToSubscription(subscription.Id, org.Id); subscription.UsageString = AzureResourceManagerUtil.GetUsage(s.Id, org.Id); //Deserialize the usage response into the usagePayload object subscription.usagePayload = JsonConvert.DeserializeObject <UsagePayload>(subscription.UsageString); List <UsageAggregate> UsageAggregateList = subscription.usagePayload.value; } else { subscription.IsConnected = false; } model.UserSubscriptions.Add(subscription.Id, subscription); if (AzureResourceManagerUtil.UserCanManageAccessForSubscription(subscription.Id, org.Id)) { model.UserCanManageAccessForSubscriptions.Add(subscription.Id); } } } else { model.DisconnectedUserOrganizations.Add(org.Id); } } } return(View(model)); }
public ActionResult Index() { HomeIndexViewModel model = null; if (ClaimsPrincipal.Current.Identity.IsAuthenticated) { model = new HomeIndexViewModel(); model.UserOrganizations = new Dictionary <Guid, Organization>(); model.UserSubscriptions = new Dictionary <Guid, Subscription>(); model.UserCanManageAccessForSubscriptions = new List <Guid>(); model.DisconnectedUserOrganizations = new List <Guid>(); var organizations = AzureResourceManagerUtil.GetUserOrganizations(); foreach (Organization org in organizations) { model.UserOrganizations.Add(org.Id, org); var subscriptions = AzureResourceManagerUtil.GetUserSubscriptions(org.Id); if (subscriptions != null) { foreach (var subscription in subscriptions) { Subscription s = db.Subscriptions.Find(subscription.Id); if (s != null) { subscription.IsConnected = true; subscription.ConnectedOn = s.ConnectedOn; subscription.ConnectedBy = s.ConnectedBy; subscription.DisplayTag = s.DisplayTag; subscription.AzureAccessNeedsToBeRepaired = !AzureResourceManagerUtil.ServicePrincipalHasReadAccessToSubscription(subscription.Id, org.Id); } else { subscription.IsConnected = false; } model.UserSubscriptions.Add(subscription.Id, subscription); if (AzureResourceManagerUtil.UserCanManageAccessForSubscription(subscription.Id, org.Id)) { model.UserCanManageAccessForSubscriptions.Add(subscription.Id); } } } else { model.DisconnectedUserOrganizations.Add(org.Id); } } } return(View(model)); }
public async Task ConnectSubscription(string subscriptionId) { string directoryId = await AzureResourceManagerUtil.GetDirectoryForSubscription(subscriptionId); if (!String.IsNullOrEmpty(directoryId)) { if (!User.Identity.IsAuthenticated || !directoryId.Equals(ClaimsPrincipal.Current.FindFirst ("http://schemas.microsoft.com/identity/claims/tenantid").Value)) { HttpContext.GetOwinContext().Environment.Add("Authority", string.Format(ConfigurationManager.AppSettings["Authority"] + "OAuth2/Authorize", directoryId)); Dictionary <string, string> dict = new Dictionary <string, string>(); dict["prompt"] = "select_account"; HttpContext.GetOwinContext().Authentication.Challenge( new AuthenticationProperties(dict) { RedirectUri = this.Url.Action("ConnectSubscription", "Home") + "?subscriptionId=" + subscriptionId }, OpenIdConnectAuthenticationDefaults.AuthenticationType); } else { string objectIdOfCloudSenseServicePrincipalInDirectory = await AzureADGraphAPIUtil.GetObjectIdOfServicePrincipalInDirectory(directoryId, ConfigurationManager.AppSettings["ClientID"]); await AzureResourceManagerUtil.GrantRoleToServicePrincipalOnSubscription (objectIdOfCloudSenseServicePrincipalInDirectory, subscriptionId, directoryId); Subscription s = new Subscription() { Id = subscriptionId, DirectoryId = directoryId, ConnectedBy = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Name).Value, ConnectedOn = DateTime.Now }; if (db.Subscriptions.Find(s.Id) == null) { db.Subscriptions.Add(s); db.SaveChanges(); } Response.Redirect(this.Url.Action("Index", "Home")); } } return; }
public ActionResult GetBillingData(string subscriptionId = "ea2939ff-05e6-4818-9a45-6cb7a2902695", string organizationId = "600d2dee-f5ea-4019-b95b-4dfb587455e0", string offerId = "MS-AZR-0063P", string currency = "USD", string language = "en-US", string regionInfo = "IN") { try { // get subscription detail from the table storage var jsonString = AzureResourceManagerUtil.GetRateCardData(subscriptionId, organizationId, offerId, currency, language, regionInfo); return(Content(jsonString, "application/json")); } catch (System.Exception exp) { Logger.Log("RateCard-Web-API", "Error", exp.Message, exp.ToString()); return(new HttpStatusCodeResult(500)); } }
public static RateCardPayload GetRateCardInfo(string restUrl, Guid orgId) { HttpWebResponse httpWebResponse = AzureResourceManagerUtil.RateCardRestApiCall(restUrl, orgId); try { if (httpWebResponse == null) { Trace.TraceWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); Trace.TraceWarning($"{nameof(httpWebResponse)} == null"); Trace.TraceWarning($" {nameof(GetRateCardInfo)}({nameof(restUrl)}, {nameof(orgId)})"); Trace.TraceWarning($" {nameof(restUrl)}: {restUrl}"); Trace.TraceWarning($" {nameof(orgId)}: {orgId}"); // throw exception to start from scretch and retry. //throw new Exception("Possible reason: Bad request (400), Forbidden (403) to access. Server busy. Client blacklisted."); } else { // look response codes @ https://msdn.microsoft.com/en-us/library/azure/mt219001.aspx // see: https://msdn.microsoft.com/en-us/library/azure/mt219004.aspx if (httpWebResponse.StatusCode == HttpStatusCode.OK) { Trace.TraceInformation($"Received Rest Call Response: {nameof(HttpStatusCode.OK)}. Processing..."); string streamContent; using (Stream receiveStream = httpWebResponse.GetResponseStream()) { // Pipes the stream to a higher level stream reader with the required encoding format. using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8)) { streamContent = readStream.ReadToEnd(); } } RateCardPayload rateCardPayload = JsonConvert.DeserializeObject <RateCardPayload>(streamContent); return(rateCardPayload); } else if (httpWebResponse.StatusCode == HttpStatusCode.Accepted) { Trace.TraceWarning($"Data not ready. {nameof(HttpStatusCode.Accepted)}. Not capable of handling this."); } else { Trace.TraceWarning("NEW RESPONSE TYPE. HANDLE THIS - GetRateCardInfo!"); Trace.TraceWarning($"code:{httpWebResponse.StatusCode} desc:{httpWebResponse.StatusDescription}"); } } return(null); } finally { httpWebResponse?.Dispose(); } }
public ActionResult GetUsageData(string subscriptionId, string organizationId, string startDate, string endDate) { try { // get subscription detail from the table storage var jsonString = AzureResourceManagerUtil.GetResourceUsageData(subscriptionId, organizationId, startDate, endDate); return(Content(jsonString, "application/json")); } catch (System.Exception exp) { Logger.Log("RateCard-Web-API", "Error", exp.Message, exp.ToString()); return(new HttpStatusCodeResult(500)); } }
public async Task RepairSubscriptionConnection(string subscriptionId) { string directoryId = await AzureResourceManagerUtil.GetDirectoryForSubscription(subscriptionId); string objectIdOfCloudSenseServicePrincipalInDirectory = await AzureADGraphAPIUtil.GetObjectIdOfServicePrincipalInDirectory(directoryId, ConfigurationManager.AppSettings["ClientID"]); await AzureResourceManagerUtil.RevokeRoleFromServicePrincipalOnSubscription (objectIdOfCloudSenseServicePrincipalInDirectory, subscriptionId, directoryId); await AzureResourceManagerUtil.GrantRoleToServicePrincipalOnSubscription (objectIdOfCloudSenseServicePrincipalInDirectory, subscriptionId, directoryId); Response.Redirect(this.Url.Action("Index", "Home")); }
public ActionResult Disconnect([Bind(Include = "Id, OrganizationId")] Subscription subscription, string servicePrincipalObjectId) { if (ModelState.IsValid) { AzureResourceManagerUtil.RevokeRoleFromServicePrincipalOnSubscription(servicePrincipalObjectId, subscription.Id, subscription.OrganizationId); Subscription s = db.Subscriptions.Find(subscription.Id); if (s != null) { db.Subscriptions.Remove(s); db.SaveChanges(); } } return(RedirectToAction("Index", "Home")); }
public ActionResult Connect([Bind(Include = "Id, OrganizationId")] Subscription subscription, string servicePrincipalObjectId) { if (ModelState.IsValid) { AzureResourceManagerUtil.GrantRoleToServicePrincipalOnSubscription(servicePrincipalObjectId, subscription.Id, subscription.OrganizationId); if (AzureResourceManagerUtil.ServicePrincipalHasReadAccessToSubscription(subscription.Id, subscription.OrganizationId)) { subscription.ConnectedBy = (System.Security.Claims.ClaimsPrincipal.Current).FindFirst(ClaimTypes.Name).Value; subscription.ConnectedOn = DateTime.Now; db.Subscriptions.Add(subscription); db.SaveChanges(); } } return(RedirectToAction("Index", "Home")); }
public ActionResult Disconnect([Bind(Include = "Id")] Subscription subscription) { if (ModelState.IsValid) { AzureResourceManagerUtil.RevokeRoleFromServicePrincipalOnSubscription(ConfigurationManager.AppSettings["ObjectId"], subscription.Id, ConfigurationManager.AppSettings["AADId"]); Subscription s = db.Subscriptions.Find(subscription.Id); if (s != null) { db.Subscriptions.Remove(s); db.SaveChanges(); } } return(RedirectToAction("Index", "Home")); }
public ActionResult RepairAccess([Bind(Include = "Id, OrganizationId")] Subscription subscription, string servicePrincipalObjectId) { if (ModelState.IsValid) { AzureResourceManagerUtil.RevokeRoleFromServicePrincipalOnSubscription(servicePrincipalObjectId, subscription.Id, subscription.OrganizationId); AzureResourceManagerUtil.GrantRoleToServicePrincipalOnSubscription(servicePrincipalObjectId, subscription.Id, subscription.OrganizationId); Subscription s = db.Subscriptions.Find(subscription.Id); if (s != null) { s.AzureAccessNeedsToBeRepaired = false; db.Entry(s).State = System.Data.Entity.EntityState.Modified; db.SaveChanges(); } } return(RedirectToAction("Index", "Home")); }
public static RateCardPayload GetRateCardInfo(string restURL, string orgID) { HttpWebResponse httpWebResponse = null; httpWebResponse = AzureResourceManagerUtil.RateCardRestApiCall(restURL, orgID); if (httpWebResponse == null) { Console.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); Console.WriteLine("httpWebResponse == null"); Console.WriteLine(" GetRateCardInfo(string restURL, string orgID)"); Console.WriteLine(" restURL: {0}", restURL); Console.WriteLine(" orgID: {0}", orgID); // throw exception to start from scretch and retry. //throw new Exception("Possible reason: Bad request (400), Forbidden (403) to access. Server busy. Client blacklisted."); } else { // look response codes @ https://msdn.microsoft.com/en-us/library/azure/mt219001.aspx if (httpWebResponse.StatusCode == HttpStatusCode.OK) { Console.WriteLine("Received Rest Call Response: HttpStatusCode.OK. Processing..."); Stream receiveStream = httpWebResponse.GetResponseStream(); // Pipes the stream to a higher level stream reader with the required encoding format. StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8); string streamContent = readStream.ReadToEnd(); RateCardPayload rateCardPayload = JsonConvert.DeserializeObject <RateCardPayload>(streamContent); return(rateCardPayload); } else if (httpWebResponse.StatusCode == HttpStatusCode.Accepted) { Console.WriteLine("Data not ready. HttpStatusCode.Accepted. Not capable of handling this."); } else { Console.WriteLine("NEW RESPONSE TYPE. HANDLE THIS - GetRateCardInfo!"); Console.WriteLine("code:{0} desc:{1}", httpWebResponse.StatusCode, httpWebResponse.StatusDescription); } } return(null); }
public async Task DisconnectSubscription(string subscriptionId) { string directoryId = await AzureResourceManagerUtil.GetDirectoryForSubscription(subscriptionId); string objectIdOfCloudSenseServicePrincipalInDirectory = await AzureADGraphAPIUtil.GetObjectIdOfServicePrincipalInDirectory(directoryId, ConfigurationManager.AppSettings["ClientID"]); await AzureResourceManagerUtil.RevokeRoleFromServicePrincipalOnSubscription (objectIdOfCloudSenseServicePrincipalInDirectory, subscriptionId, directoryId); Subscription s = db.Subscriptions.Find(subscriptionId); if (s != null) { db.Subscriptions.Remove(s); db.SaveChanges(); } Response.Redirect(this.Url.Action("Index", "Home")); }
public List <Subscription> Get() { var tenantId = ClaimsPrincipal.Current.TenantId(); var subscriptions = AzureResourceManagerUtil.GetUserSubscriptions(tenantId); var dbSubscriptions = this.coreRepository.GetSubscriptionListByOrgId(tenantId); foreach (var subscription in subscriptions) { var dbSub = dbSubscriptions.FirstOrDefault(x => x.Id == subscription.Id); if (dbSub != null) { subscription.ConnectedOn = dbSub.ConnectedOn; subscription.ConnectedBy = dbSub.ConnectedBy; subscription.StorageName = dbSub.StorageName; subscription.IsEnrolled = dbSub.IsEnrolled; subscription.IsConnected = dbSub.IsConnected; subscription.ContributorGroups = dbSub.ContributorGroups; } } return(subscriptions); }
public ActionResult Index() { HomeIndexViewModel model = null; if (ClaimsPrincipal.Current.Identity.IsAuthenticated) { model = new HomeIndexViewModel(); model.UserSubscriptions = new Dictionary <string, Subscription>(); model.UserCanManageAccessForSubscriptions = new List <string>(); var subscriptions = AzureResourceManagerUtil.GetUserSubscriptions(ConfigurationManager.AppSettings["AADId"]); if (subscriptions != null) { foreach (var subscription in subscriptions) { Subscription s = db.Subscriptions.Find(subscription.Id); if (s != null) { subscription.IsConnected = true; subscription.ConnectedOn = s.ConnectedOn; subscription.ConnectedBy = s.ConnectedBy; subscription.AzureAccessNeedsToBeRepaired = !AzureResourceManagerUtil.ServicePrincipalHasReadAccessToSubscription (subscription.Id, ConfigurationManager.AppSettings["AADId"]); } else { subscription.IsConnected = false; } model.UserSubscriptions.Add(subscription.Id, subscription); if (AzureResourceManagerUtil.UserCanManageAccessForSubscription(subscription.Id, ConfigurationManager.AppSettings["AADId"])) { model.UserCanManageAccessForSubscriptions.Add(subscription.Id); } } } } return(View(model)); }
public ActionResult Connect([Bind(Include = "Id, OrganizationId, DisplayName")] Subscription subscription, string servicePrincipalObjectId, string displayTag) { if (ModelState.IsValid) { AzureResourceManagerUtil.RevokeRoleFromServicePrincipalOnSubscription(servicePrincipalObjectId, subscription.Id, subscription.OrganizationId); AzureResourceManagerUtil.GrantRoleToServicePrincipalOnSubscription(servicePrincipalObjectId, subscription.Id, subscription.OrganizationId); if (AzureResourceManagerUtil.ServicePrincipalHasReadAccessToSubscription(subscription.Id, subscription.OrganizationId)) { // Insert into SQL DB subscription.ConnectedBy = (System.Security.Claims.ClaimsPrincipal.Current).FindFirst(ClaimTypes.Name).Value; subscription.ConnectedOn = DateTime.Now; subscription.AzureAccessNeedsToBeRepaired = false; subscription.DisplayTag = displayTag; subscription.DataGenDate = DateTime.UtcNow; subscription.DataGenStatus = DataGenStatus.Pending; db.Subscriptions.Add(subscription); db.SaveChanges(); DateTime sdt = DateTime.Now.AddYears(-3); DateTime edt = DateTime.Now.AddDays(-1); BillingRequest br = new BillingRequest(subscription.Id, subscription.OrganizationId, sdt, edt); // Insert into Azure Storage Queue var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["AzureWebJobsStorage"].ToString()); CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient(); CloudQueue subscriptionsQueue = queueClient.GetQueueReference(ConfigurationManager.AppSettings["ida:QueueBillingDataRequests"].ToString()); subscriptionsQueue.CreateIfNotExists(); var queueMessage = new CloudQueueMessage(JsonConvert.SerializeObject(br)); subscriptionsQueue.AddMessageAsync(queueMessage); } } return(RedirectToAction("Index", "Home")); }
public async Task <ActionResult> Index() { ViewModel model = null; if (ClaimsPrincipal.Current.Identity.IsAuthenticated) { string userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Name).Value; model = new ViewModel(); model.ConnectedSubscriptions = new List <Subscription>(); var connectedSubscriptions = db.Subscriptions.Where <Subscription>(s => s.ConnectedBy == userId); foreach (var connectedSubscription in connectedSubscriptions) { bool servicePrincipalHasReadAccessToSubscription = await AzureResourceManagerUtil. DoesServicePrincipalHaveReadAccessToSubscription(connectedSubscription.Id, connectedSubscription.DirectoryId); connectedSubscription.AzureAccessNeedsToBeRepaired = !servicePrincipalHasReadAccessToSubscription; model.ConnectedSubscriptions.Add(connectedSubscription); } } return(View(model)); }
public async Task <UserSubscriptionInfo> GetUserDetailsFull() { var subscriptionInfo = new UserSubscriptionInfo(); subscriptionInfo.UserName = ClaimsPrincipal.Current.Identity.Name; subscriptionInfo.FirstName = ClaimsPrincipal.Current.FirstName(); subscriptionInfo.LastName = ClaimsPrincipal.Current.LastName(); subscriptionInfo.DefaultAdGroup = Config.DefaultAdGroup; subscriptionInfo.DefaultResourceGroup = Config.DefaultResourceGroup; string tenantId = ClaimsPrincipal.Current.TenantId(); string signedInUserUniqueId = ClaimsPrincipal.Current.SignedInUserName(); var userGroupsRoles = AzureADGraphApiUtil.GetUserGroups(signedInUserUniqueId, tenantId); subscriptionInfo.IsGlobalAdministrator = AzureADGraphApiUtil.IsGlobalAdministrator(userGroupsRoles); var org = GetOrganization(tenantId); var dbOrg = await this.coreRepository.GetOrganization(tenantId); List <Subscription> dbSubscriptions = null; if (dbOrg != null) { org.DeployGroup = dbOrg.DeployGroup; org.CreateProductGroup = dbOrg.CreateProductGroup; org.AdminGroup = dbOrg.AdminGroup; //var userGroups = AzureADGraphApiUtil.GetUserGroups(signedInUserUniqueId, org.Id); subscriptionInfo.CanCreate = userGroupsRoles.Any(x => x.Id == dbOrg.CreateProductGroup); subscriptionInfo.CanDeploy = userGroupsRoles.Any(x => x.Id == dbOrg.DeployGroup); subscriptionInfo.CanAdmin = userGroupsRoles.Any(x => x.Id == dbOrg.AdminGroup); dbSubscriptions = this.coreRepository.GetSubscriptionListByOrgId(tenantId); if (dbSubscriptions != null && dbSubscriptions.Count > 0) { subscriptionInfo.IsActivatedByAdmin = (dbSubscriptions.Any(x => x.IsConnected)); } } subscriptionInfo.Organization = org; var orgGroups = AzureADGraphApiUtil.GetAllGroupsForOrganization(org.Id); subscriptionInfo.OrganizationADGroups = orgGroups; var subscriptions = AzureResourceManagerUtil.GetUserSubscriptions(org.Id); if (subscriptions != null) { foreach (var subscription in subscriptions) { var userDetailVM = new UserDetailsViewModel(); userDetailVM.CanCreate = subscriptionInfo.CanCreate; userDetailVM.CanDeploy = subscriptionInfo.CanDeploy; userDetailVM.CanAdmin = subscriptionInfo.CanAdmin; userDetailVM.Name = subscriptionInfo.UserName; userDetailVM.IsAdminOfSubscription = AzureResourceManagerUtil.UserCanManageAccessForSubscription(subscription.Id); userDetailVM.SubscriptionName = subscription.DisplayName; userDetailVM.SubscriptionId = subscription.Id; userDetailVM.OrganizationId = org.Id; userDetailVM.ServicePrincipalId = org.ObjectIdOfCloudSenseServicePrincipal; userDetailVM.OrganizationName = org.DisplayName; Subscription dbSubscription = null; if (dbSubscriptions != null && dbSubscriptions.Count > 0) { dbSubscription = dbSubscriptions.FirstOrDefault(x => x.Id == subscription.Id) ?? null; } if (dbSubscription != null) { userDetailVM.SubscriptionIsConnected = dbSubscription.IsConnected;// true; userDetailVM.IsEnrolled = dbSubscription.IsEnrolled; userDetailVM.SubscriptionNeedsRepair = !AzureResourceManagerUtil.ServicePrincipalHasReadAccessToSubscription(dbSubscription.Id); if (userDetailVM.SubscriptionIsConnected) { string organizationId = dbSubscription.OrganizationId; string storageName = dbSubscription.StorageName; try { string storageKey = await AzureResourceManagerUtil.GetStorageAccountKeysArm(dbSubscription.Id, dbSubscription.StorageName); CacheDetails(userDetailVM, storageKey, storageName, organizationId, signedInUserUniqueId); } catch (Exception ex) { Trace.TraceError(ex.Message); Trace.TraceError($"Storage account: {storageName} was not found!"); userDetailVM.SubscriptionIsConnected = false; userDetailVM.IsEnrolled = false; } } } subscriptionInfo.Subscriptions.Add(userDetailVM); } } return(subscriptionInfo); }
public static List <UsageRecord> GetUsageDetails(string restUrl, Guid orgId, RateCardPayload rateCardInfo) { string nextLink = ""; List <UsageRecord> usageRecords = new List <UsageRecord>(); do { HttpWebResponse httpWebResponse = null; try { if (nextLink != "") { httpWebResponse = AzureResourceManagerUtil.BillingRestApiCall(nextLink, orgId); } else { httpWebResponse = AzureResourceManagerUtil.BillingRestApiCall(restUrl, orgId); } if (httpWebResponse == null) { Trace.TraceWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); Trace.TraceWarning($"{nameof(httpWebResponse)} == null"); Trace.TraceWarning($" {nameof(GetUsageDetails)}({nameof(restUrl)}, {nameof(orgId)})"); Trace.TraceWarning($" {nameof(restUrl)}: {restUrl}"); Trace.TraceWarning($" {nameof(orgId)}: {orgId}"); // throw exception to start from scretch and retry. //throw new Exception("Possible reason: Bad request (400), Forbidden (403) to access. Server busy. Client blacklisted."); } else { // look response codes @ https://msdn.microsoft.com/en-us/library/azure/mt219001.aspx if (httpWebResponse.StatusCode == HttpStatusCode.OK) { Trace.TraceInformation($"Received Rest Call Response: {nameof(HttpStatusCode.OK)}. Processing..."); string streamContent; using (Stream receiveStream = httpWebResponse.GetResponseStream()) { // Pipes the stream to a higher level stream reader with the required encoding format. using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8)) { streamContent = readStream.ReadToEnd(); } } UsagePayload usagePayload = JsonConvert.DeserializeObject <UsagePayload>(streamContent); foreach (UsageAggregate ua in usagePayload.Value) { // handle adding cost in var usageRecord = new UsageRecord(ua); try { var meterInfo = rateCardInfo.Meters.Where(p => p.MeterId == usageRecord.MeterId).SingleOrDefault(); if (meterInfo.MeterRates.Count > 1) { Trace.TraceWarning("Multiple rates for meter: " + usageRecord.MeterId); } usageRecord.Cost = (double)meterInfo.MeterRates["0"] * usageRecord.Quantity; //if (usageRecord.cost < 0.01) usageRecord.cost = 0; // TODO: usage cost is definitelly NOT rounded like this } catch (Exception ex) { Trace.TraceError("Exception trying to apply cost info for meter: " + usageRecord.MeterId); } usageRecords.Add(usageRecord); } ContinuationToken contToken = JsonConvert.DeserializeObject <ContinuationToken>(streamContent); nextLink = contToken.NextLink ?? ""; } else if (httpWebResponse.StatusCode == HttpStatusCode.Accepted) { Trace.TraceWarning($"Data not ready. {nameof(HttpStatusCode.Accepted)}. Waiting 6 min. now: {DateTime.UtcNow}"); Thread.Sleep(1000 * 60 * 6); // wait a bit to have data get prepared by azure nextLink = restUrl; // set next link to same URL for second call } else { Trace.TraceWarning("NEW RESPONSE TYPE. HANDLE THIS!"); Trace.TraceWarning($"code:{httpWebResponse.StatusCode} desc:{httpWebResponse.StatusDescription}"); } } } finally { httpWebResponse?.Dispose(); } } while (nextLink != ""); return(usageRecords); }
public static void ProcessQueueMessage([QueueTrigger("billingdatarequests")] BillingRequest billingRequest, TextWriter logWriter = null) { if (logWriter != null) { TextWriterTraceListener traceListener = new TextWriterTraceListener(logWriter, "LogWriter"); Trace.Listeners.Remove("LogWriter"); Trace.Listeners.Add(traceListener); Trace.TraceInformation("Azure WebJob Log Writer configured"); } Trace.TraceInformation($"WebJob process started. {nameof(billingRequest.SubscriptionId)}: {billingRequest.SubscriptionId}"); int retriesLeft = Convert.ToInt32(RetryCountToProcessMessage); Exception lastException = null; while (retriesLeft > 0) { --retriesLeft; if (retriesLeft < 1) { Trace.TraceInformation($"Finished internal retries, time:{DateTime.UtcNow}"); if (lastException != null) { throw lastException; } else { return; } } Trace.TraceInformation($"Start time:{DateTime.UtcNow}, retries Left: {retriesLeft}"); try { //Fetch RateCard information First string rateCardUrl = AzureResourceManagerUtil.GetRateCardRestApiCallURL(billingRequest.SubscriptionId, OfferCode, Currency, Locale, RegionInfo); Trace.TraceInformation("Request cost info from RateCard service."); RateCardPayload rateCardInfo = GetRateCardInfo(rateCardUrl, billingRequest.OrganizationId); if (rateCardInfo == null) { Trace.TraceWarning("Problem receiving cost info occured - see log for details."); continue; } else { Trace.TraceInformation("Received cost info: " + rateCardInfo.ToString()); } // if granularity=hourly then report up to prev. hour, // if granularity=daily then report up to prev. day. Othervise will get 400 error //DateTime sdt = DateTime.UtcNow.Date.AddYears(-3); //DateTime edt = DateTime.UtcNow.Date.AddDays(-1); // see: https://msdn.microsoft.com/en-us/library/azure/mt219004.aspx string restUrl = AzureResourceManagerUtil.GetBillingRestApiCallUrl(billingRequest.SubscriptionId, true, true, billingRequest.StartDate, billingRequest.EndDate); Trace.TraceInformation("Request usage data from Billing service."); var usageRecords = GetUsageDetails(restUrl, billingRequest.OrganizationId, rateCardInfo); Trace.TraceInformation($"Received record count: {usageRecords.Count}"); if (usageRecords.Count > 0) { Trace.TraceInformation("Inserting usage records into SQL database."); Task <int> task = InsertIntoSqlDbAsync(usageRecords, billingRequest.SubscriptionId, billingRequest.StartDate, billingRequest.EndDate); int recordCount = task.GetAwaiter().GetResult(); Trace.TraceInformation($"Total {recordCount} usage record(s) inserted."); } else { Trace.TraceInformation("No usage data found."); } break; } catch (Exception e) { Trace.TraceError($"Exception: {nameof(ProcessQueueMessage)} -> e.Message: " + e.Message); lastException = e; if (retriesLeft == 0) { throw; } } Trace.TraceInformation($"Sleeping in {nameof(ProcessQueueMessage)} while loop for 5 min. DateTime: {DateTime.UtcNow}"); Thread.Sleep(1000 * 60 * 5); } // while Utils.UpdateSubscriptionStatus(billingRequest.SubscriptionId, DataGenStatus.Completed, DateTime.UtcNow); Trace.TraceInformation($"WebJob process completed. SubscriptionId: {billingRequest.SubscriptionId}"); }
public static void ProcessQueueMessage([QueueTrigger("billingdatarequests")] BillingRequest br) { Console.WriteLine("Start webjob process. SubscriptionID: {0}", br.SubscriptionId); int retriesLeft = Convert.ToInt32(ConfigurationManager.AppSettings["ida:RetryCountToProcessMessage"].ToString()); while (retriesLeft > 0) { --retriesLeft; if (retriesLeft < 1) { Console.WriteLine("Finished internal retries, throwing exception. Time:{0}", DateTime.UtcNow.ToString()); throw new Exception(); } Console.WriteLine("Start time:{0} Retries Left: {1}", DateTime.UtcNow.ToString(), retriesLeft); try { //Fetch RateCard information First string rateCardURL = AzureResourceManagerUtil.GetRateCardRestApiCallURL(br.SubscriptionId, ConfigurationManager.AppSettings["ida:OfferCode"].ToString(), ConfigurationManager.AppSettings["ida:Currency"].ToString(), ConfigurationManager.AppSettings["ida:Locale"].ToString(), ConfigurationManager.AppSettings["ida:RegionInfo"].ToString()); Console.WriteLine("Request cost info from RateCard service."); RateCardPayload rateCardInfo = GetRateCardInfo(rateCardURL, br.OrganizationId); if (rateCardInfo == null) { Console.WriteLine("Problem receiving cost info occured - see log for details."); continue; } else { Console.WriteLine("Received cost info: " + rateCardInfo.ToString()); } // if granularity=hourly then report up to prev. hour, // if granularity=daily then report up to prev. day. Othervise will get 400 error //DateTime sdt = DateTime.Now.AddYears(-3); //DateTime edt = DateTime.Now.AddDays(-1); string restURL = AzureResourceManagerUtil.GetBillingRestApiCallURL(br.SubscriptionId, false, true, br.StartDate, br.EndDate); Console.WriteLine("Request usage data from Billing service."); List <UsageRecord> urs = GetUsageDetails(restURL, br.OrganizationId, rateCardInfo); Console.WriteLine("Received record count: {0}", urs.Count); Console.WriteLine("Insert usage data into SQL Server."); InsertIntoSQLDB(urs); break; } catch (Exception e) { Console.WriteLine("Exception: ProcessQueueMessage->e.Message: " + e.Message); if (retriesLeft == 0) { throw; } } Console.WriteLine("Sleeping in ProcessQueueMessage while loop for 5 min. DateTime: {0}", DateTime.Now.ToString()); Thread.Sleep(1000 * 60 * 5); } // while Commons.Utils.UpdateSubscriptionStatus(br.SubscriptionId, DataGenStatus.Completed, DateTime.UtcNow); Console.WriteLine("Complete webjob process. SubscriptionID: {0}", br.SubscriptionId); }
public static List <UsageRecord> GetUsageDetails(string restURL, string orgID, RateCardPayload rateCardInfo) { string nextLink = ""; List <UsageRecord> usageRecords = new List <UsageRecord>(); do { HttpWebResponse httpWebResponse = null; if (nextLink != "") { httpWebResponse = AzureResourceManagerUtil.BillingRestApiCall(nextLink, orgID); } else { httpWebResponse = AzureResourceManagerUtil.BillingRestApiCall(restURL, orgID); } if (httpWebResponse == null) { Console.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); Console.WriteLine("httpWebResponse == null"); Console.WriteLine(" GetUsageDetails(string restURL, string orgID)"); Console.WriteLine(" restURL: {0}", restURL); Console.WriteLine(" orgID: {0}", orgID); // throw exception to start from scretch and retry. //throw new Exception("Possible reason: Bad request (400), Forbidden (403) to access. Server busy. Client blacklisted."); } else { // look response codes @ https://msdn.microsoft.com/en-us/library/azure/mt219001.aspx if (httpWebResponse.StatusCode == HttpStatusCode.OK) { Console.WriteLine("Received Rest Call Response: HttpStatusCode.OK. Processing..."); Stream receiveStream = httpWebResponse.GetResponseStream(); // Pipes the stream to a higher level stream reader with the required encoding format. StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8); string streamContent = readStream.ReadToEnd(); UsagePayload usagePayload = JsonConvert.DeserializeObject <UsagePayload>(streamContent); foreach (UsageAggregate ua in usagePayload.value) { //Handle adding cost in var ur = new UsageRecord(ua); try { var meterInfo = rateCardInfo.Meters.Where(p => p.MeterId == ur.meterId).SingleOrDefault(); ur.cost = meterInfo.MeterRates["0"] * Convert.ToDecimal(ur.quantity); if (ur.cost < 0.01M) { ur.cost = 0; } } catch (Exception ex) { Console.WriteLine("Exception trying to apply cost info for meter: " + ur.meterId); } usageRecords.Add(ur); } ContinuationToken contToken = JsonConvert.DeserializeObject <ContinuationToken>(streamContent); if (contToken.nextLink != null) { nextLink = contToken.nextLink; } else { nextLink = ""; } } else if (httpWebResponse.StatusCode == HttpStatusCode.Accepted) { Console.WriteLine("Data not ready. HttpStatusCode.Accepted. Waiting 6 min. now: {0}", DateTime.Now.ToString()); Thread.Sleep(1000 * 60 * 6); // wait a bit to have data get prepared by azure nextLink = restURL; // set next link to same URL for second call } else { Console.WriteLine("NEW RESPONSE TYPE. HANDLE THIS!"); Console.WriteLine("code:{0} desc:{1}", httpWebResponse.StatusCode, httpWebResponse.StatusDescription); } } } while (nextLink != ""); return(usageRecords); }
/// <summary> /// Method to collect azure usage records from Azure APIs. /// </summary> /// <returns>Collection of Usage records.</returns> private IEnumerable <UsageInfoModel> GetUsageInfo() { // Loop for every subscription foreach (var subscription in this.subscriptions) { // Get usage details for subscription RateCardPayload rates = AzureResourceManagerUtil.GetRates(subscription.Id, org.Id, authResult); List <UsageAggregate> usageList = AzureResourceManagerUtil.GetUsage( subscription.Id, org.Id, authResult, this.startDate, this.endDate); IEnumerable <string> projects = AzureResourceManagerUtil.GetUniqueProjects(usageList); subscription.Projects = projects; IEnumerable <ProjectUsage> projectTotals = AzureResourceManagerUtil.GetProjectIDTotals(usageList, projects); subscription.ProjectTotals = projectTotals; IEnumerable <ProjectRate> projectRates = AzureResourceManagerUtil.GetProjectRates( rates, projectTotals); subscription.ProjectRates = projectRates; IEnumerable <ProjectEstimate> projectEstimateTotals = AzureResourceManagerUtil.RatedEstimateForProject(projectRates); subscription.ProjectEstimateTotals = projectEstimateTotals; IEnumerable <string> resourceList = AzureResourceManagerUtil.GetResources(usageList); IEnumerable <ResourceUsage> resourceUsages = AzureResourceManagerUtil.GetResourceUsage(usageList, resourceList); subscription.ResourceTotals = AzureResourceManagerUtil.GetResourceTotals(resourceList, usageList); IEnumerable <ResourceRate> resourceRates = AzureResourceManagerUtil.GetResourceRates(rates, resourceUsages); IEnumerable <ResourceEstimate> resourceEstimates = AzureResourceManagerUtil.RatedEstimateForResource(resourceRates); subscription.ResourceEstimates = resourceEstimates; subscription.MeterIdTotals = AzureResourceManagerUtil.GetMeterIdTotals(usageList); subscription.ServiceTotals = AzureResourceManagerUtil.GetServiceTotals(usageList); var result = JsonConvert.SerializeObject(subscription.MeterIdTotals); // Input to graphing solution subscription.UsageDetails = result; IEnumerable <RatedUsage> ratedUsageList = AzureResourceManagerUtil.GetMeterIDRates( AzureResourceManagerUtil.GetMeterIdTotals(usageList), rates); subscription.ratedUsage = ratedUsageList; subscription.RatedEstimate = AzureResourceManagerUtil.RatedEstimate(ratedUsageList); foreach (var usg in usageList) { double usgtot = AzureResourceManagerUtil.ComputeRatedUsagePerMeter( AzureResourceManagerUtil.GetRatesForMeterID(rates, usg.properties.meterId), usg.properties.quantity); this.usageInfo.Add(new UsageInfoModel() { OrganizationId = org.Id, SubceriptionId = subscription.Id, UsageStartTime = usg.properties.usageStartTime, UsageEndTime = usg.properties.usageEndTime, MeteredRegion = usg.properties.infoFields.MeteredRegion, MeterName = usg.properties.meterName, MeteredService = usg.properties.infoFields.MeteredService, MeteredServiceType = usg.properties.infoFields.MeteredServiceType, MeterCategory = usg.properties.meterCategory, MeterSubCategory = usg.properties.meterSubCategory, UserProject = usg.properties.infoFields.Project, Quantity = usg.properties.quantity, ItemTotal = usgtot }); } } return(this.usageInfo); }