11
2- var Batch = require ( 'batch' ) ;
32var bind = require ( 'bind' ) ;
43var csv = require ( 'csv' ) ;
54var debug = require ( 'debug' ) ( 'aws-billing' ) ;
65var Ec2 = require ( 'awssum-amazon-ec2' ) . Ec2 ;
76var knox = require ( 'knox' ) ;
8- var once = require ( 'once' ) ;
9- var prices = require ( './ec2-prices' ) ;
7+ var Dates = require ( 'date-math' ) ;
108
119/**
1210 * Expose `AWSBilling`.
@@ -47,52 +45,28 @@ function AWSBilling (accountId, key, secret, bucket, region) {
4745 */
4846
4947AWSBilling . prototype . get = function ( callback ) {
50- new Batch ( this . getEc2 , this . getNonEc2 ) . end ( function ( err , results ) {
48+ this . products ( function ( err , products ) {
5149 if ( err ) return callback ( err ) ;
52- callback ( null , {
53- ec2 : results [ 0 ] ,
54- nonEc2 : results [ 1 ] ,
55- total : results [ 0 ] + results [ 1 ]
50+ var total = 0.0 ;
51+ Object . keys ( products ) . forEach ( function ( product ) {
52+ total += products [ product ] ;
5653 } ) ;
57- } ) ;
58- } ;
59-
60- /**
61- * Get the current cost of EC2 instances.
62- *
63- * @param {Function } callback
64- */
65-
66- AWSBilling . prototype . getEc2 = function ( callback ) {
67- callback = once ( callback ) ; // hack: get rid of a horrible AWS sdk bug
68- var self = this ;
69- debug ( 'describing ec2 instances ..' ) ;
70- this . ec2 . DescribeInstances ( function ( err , res ) {
71- if ( err ) return callback ( err ) ;
72- var reservations = res . Body . DescribeInstancesResponse . reservationSet . item ; // wow, wtf?
73- var instances = [ ] ;
74- reservations . forEach ( function ( r ) {
75- var item = r . instancesSet . item ;
76- if ( Array . isArray ( item ) ) instances . push . apply ( instances , item ) ;
77- else instances . push ( item ) ;
54+ callback ( null , {
55+ total : total ,
56+ start : Dates . month . floor ( new Date ( ) ) ,
57+ end : new Date ( ) ,
58+ products : products
7859 } ) ;
79- debug ( 'described ec2 instances' ) ;
80- var cost = instances
81- . filter ( function ( i ) { return i . instanceState . name === 'running' ; } )
82- . map ( function ( i ) { return prices [ i . instanceType ] * 24 * 30 ; } )
83- . reduce ( function ( memo , cost ) { return memo + parseFloat ( cost ) ; } , 0 ) ;
84- debug ( 'monthly ec2 cost: $%d' , cost ) ;
85- callback ( null , cost ) ;
8660 } ) ;
8761} ;
8862
8963/**
90- * Get the cost of non-EC2 AWS stuff.
64+ * Get the cost of AWS products
9165 *
9266 * @param {Function } callback
9367 */
9468
95- AWSBilling . prototype . getNonEc2 = function ( callback ) {
69+ AWSBilling . prototype . products = function ( callback ) {
9670 var accountId = this . accountId . replace ( / - / g, '' ) ;
9771 var now = new Date ( ) ;
9872 var file = accountId + '-aws-billing-csv-' +
@@ -104,19 +78,21 @@ AWSBilling.prototype.getNonEc2 = function (callback) {
10478 csv ( )
10579 . from . stream ( stream )
10680 . to . array ( function ( data ) {
107- var productCol = data [ 0 ] . indexOf ( 'ProductCode' ) ;
81+ var products = { } ;
82+ var productCol = data [ 0 ] . indexOf ( 'ProductCode' ) + 1 ;
10883 var costCol = data [ 0 ] . indexOf ( 'TotalCost' ) ;
109- var cost = data
110- . filter ( function ( row ) {
111- return row [ productCol ] &&
112- row [ productCol ] !== 'AmazonEC2' &&
113- ! isNaN ( row [ costCol ] ) ;
114- } )
115- . reduce ( function ( memo , row ) { return memo + parseFloat ( row [ costCol ] ) ; } , 0 ) ;
116- var monthFraction = new Date ( ) . getDate ( ) / 30 ;
117- var rolling30DayCost = cost / monthFraction ;
118- debug ( 'rolling 30 days non-ec2 cost: %d' , rolling30DayCost ) ;
119- callback ( err , rolling30DayCost ) ;
84+ data . forEach ( function ( row ) {
85+ var product = row [ productCol ] . toLowerCase ( )
86+ . replace ( / a m a z o n / , '' )
87+ . replace ( / a w s / , '' ) ;
88+ var cost = parseFloat ( row [ costCol ] ) ;
89+ if ( product && cost > 0 ) {
90+ if ( ! products [ product ] ) products [ product ] = 0 ;
91+ products [ product ] += cost ;
92+ }
93+ } ) ;
94+ debug ( 'parsed AWS product costs' ) ;
95+ callback ( err , products ) ;
12096 } ) ;
12197 } ) ;
12298} ;
0 commit comments