private static void ProcessRateCard(AzureRateCard rateCard, TraceWriter log) { if (rateCard.Meters != null) { log.Info($"Inserting rate card data into database"); DumpUtility blkOperation = new DumpUtility(ConfigurationHelper.GetConnectionString(ConfigurationKeys.DbConnectoinString)); //Sometimes effective data is returned incorrect such as 01/01/0001 which is not a valid date for SQL and throws exception as below //System.Data: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM // Hence to support this data, the date is changed to 1/1/1753 blkOperation.Insert <CspAzureRateCard>(rateCard.Meters.Select(s => new CspAzureRateCard() { MeterId = s.Id, MeterName = s.Name, RateKey = string.Join(",", s.Rates.Keys), RateValue = string.Join(",", s.Rates.Values), Tags = string.Join(",", s.Tags), Category = s.Category, SubCategory = s.Subcategory, Region = s.Region, Unit = s.Unit, IncludedQuantity = s.IncludedQuantity, EffectiveDate = s.EffectiveDate.Year < 1753 ? new DateTime(1753, 1, 1) : s.EffectiveDate }).ToList()); log.Info($"Database operation completed."); } }
/// <summary> /// Prints line items that represents the combination of rate card and utilization records. /// </summary> /// <param name="rateCard">Rate card details for Azure resources.</param> /// <param name="records">A list of Azure utilization records.</param> /// <remarks> /// The calculations performed by this method do not included quantities and do not take tiered pricing into /// consideration. Both were omittied for the sake of simiplicity. If you want to ensure the calculations /// match the reconciliation file then you will need to the appropriate logic. Please note that the included /// quantity value specifies the included quantity for the billing cycle. The billing cycle is when Microsoft /// sends the partner an invoice for all services consumed through the Cloud Solution Provider program. /// </remarks> private static void PrintLineItems(AzureRateCard rateCard, List <AzureUtilizationRecord> records) { List <LineItem> items; try { ConsoleHelper.Instance.StartProgress("Combining utilization records with rate card details"); items = new List <LineItem>(); items = records.Select(r => new LineItem { Category = r.Resource.Category, Id = r.Resource.Id, Name = r.Resource.Name, Price = rateCard.Meters.Single(m => m.Id == r.Resource.Id).Rates[0] * r.Quantity, Quantity = r.Quantity, Region = r.Resource.Region, ResourceUri = r.InstanceData.ResourceUri, Subcategory = r.Resource.Category, UsageEndTime = r.UsageEndTime, UsageStartTime = r.UsageStartTime }).ToList(); ConsoleHelper.Instance.StopProgress(); ConsoleHelper.Instance.WriteObject(items); } finally { items = null; } }
//downloader.OfferId = "MS-AZR-0003P"; //PAYG //downloader.Currency = "KRW"; //downloader.RegionInfo = "KR"; //downloader.Locale = "en-US"; private void ProcessPAYG() { try { AzureRateCard rateCard = downloader.DownloadPAYG().Result; uploder.BulkUpload(rateCard.Meters, GetAppSetting("DatabaseId"), GetAppSetting("PAYGCollectionId")).Wait(); } catch (Exception e) { Console.WriteLine("Import failed:" + e.Message); } }
// CRON expressions format:: {second} {minute} {hour} {day} {month} {day-of-week} public static async Task RunAync([TimerTrigger("0 0 10 1/1 * *")] TimerInfo myTimer, TraceWriter log) #endif { log.Info($"Get azure rate function execution started at {DateTime.UtcNow} UTC"); try { log.Info($"Database initialization started."); DbInitializer.init(ConfigurationHelper.GetConnectionString(ConfigurationKeys.DbConnectoinString)); log.Info($"Database initialization completed."); string partnerServiceApiRoot = ConfigurationHelper.GetAppSetting(ConfigurationKeys.MPN.PartnerServiceApiRoot), authority = ConfigurationHelper.GetAppSetting(ConfigurationKeys.MPN.Authority), resourceUrl = ConfigurationHelper.GetAppSetting(ConfigurationKeys.MPN.ResourceUrl), applicationId = ConfigurationHelper.GetAppSetting(ConfigurationKeys.MPN.ApplicationId), applicationSecret = ConfigurationHelper.GetAppSetting(ConfigurationKeys.MPN.ApplicationSecret), applicationDomian = ConfigurationHelper.GetAppSetting(ConfigurationKeys.MPN.ApplicationDomain), RateCardCurrancy = ConfigurationHelper.GetAppSetting(ConfigurationKeys.AzureRatesApi.Currancy), RateCardRegion = ConfigurationHelper.GetAppSetting(ConfigurationKeys.AzureRatesApi.Region); log.Verbose($"Partner Service Api Root {partnerServiceApiRoot}"); log.Verbose($"Authority is {authority}"); log.Verbose($"Resource URL is {resourceUrl}"); log.Verbose($"Application Id is {applicationId}"); log.Verbose($"Application Secret is {new string('*', applicationSecret.Length)}"); log.Verbose($"Application Domain is {applicationDomian}"); log.Info($"Connecting to MPN network"); MpnApiClient mpnClient = await MpnApiClient.CreateAsync(partnerServiceApiRoot , authority , resourceUrl , applicationId , applicationSecret , applicationDomian); log.Info($"Connected to MPN network"); AzureRateCard rateCard = await mpnClient.GetAzureRateCardAsync(RateCardCurrancy, RateCardRegion); if (rateCard != null) { ProcessRateCard(rateCard, log); } log.Info($"Finished processing rate card"); } catch (Exception ex) { log.Error("Some error occured in function - 'GetAzureRates'", ex); } log.Info($"Get azure rate function execution completed at {DateTime.UtcNow} UTC"); }
/// <summary> /// Initializes a new instance of the <see cref="PSAzureRateCard" /> class. /// </summary> /// <param name="rateCard">The base rate card for this instance.</param> public PSAzureRateCard(AzureRateCard rateCard) { this.CopyFrom(rateCard); }
/// <summary> /// Prints line items that represents the combination of rate card and utilization records. /// </summary> /// <param name="rateCard">Rate card details for Azure resources.</param> /// <param name="records">A list of Azure utilization records.</param> private static void PrintLineItems(AzureRateCard rateCard, List <AzureUtilizationRecord> records) { }