This code computes the current hourly and monthly cost of a project on Google Compute Engine. It uses this pricing page as the reference.
Read all the files produced by gcutil. Then turn each file content into json.
fs = require 'fs'
read = (file) ->
content = fs.readFileSync "data/#{file}.json", {encoding: 'UTF-8'}
JSON.parse(content).itemsclass CostComputer
constructor: (data) ->
@count = {}
@count[key] = value.length for key,value of data
@cost = 0.0
@cost += @instanceCost(instance) for instance in data.instances
@cost += @diskCost(disk) for disk in data.disks
@cost += @snapshotCost(snapshot) for snapshot in data.snapshotsEach type of none-TERMINATED instance has a specific hourly cost. Source
instanceCost: (instance) ->
return 0 if instance.status is 'TERMINATED'
switch @type(instance.machineType)
when 'n1-standard-1' then 0.104
when 'n1-standard-2' then 0.207
when 'n1-standard-4' then 0.415
when 'n1-standard-8' then 0.829
when 'n1-standard-16' then 1.659
else throw "Unknown machine type #{instance.machineType}"
type: (machineType) ->
machineType.split('/').last()There's a monthly cost per Gb used. Source
diskCost: (disk) ->
@daily(disk.sizeGb * 0.04) snapshotCost: (snapshot) ->
@daily(snapshot.diskSizeGb * 0.125)It's currently just an approximation.
monthly: (daily) ->
daily * (24 * 31) # pessimist
daily: (monthly) ->
monthly / (24 * 30) # pessimistPrint hourly and monthly cost and the number of moving parts used (instances, disks, snapshots...).
print: -> console.log """
Current cost is:
- $#{@cost} per hour
- $#{@monthly(@cost)} per month
For:
- #{@count.instances} instance(s)
- #{@count.disks} disk(s)
- #{@count.snapshots} snapshot(s)
"""Extend Array class to be able to get its last value:
Array::last ?= (n) ->
if n? then @[(Math.max @length - n, 0)...] else @[@length - 1]new CostComputer
instances: read 'listinstances'
disks: read 'listdisks'
snapshots: read 'listsnapshots'
.print()There's still a lot to be done: