Skip to content

Instantly share code, notes, and snippets.

@ajayverghese
Last active August 29, 2015 14:18
Show Gist options
  • Save ajayverghese/c7f6971b0418ed55a3dc to your computer and use it in GitHub Desktop.
Save ajayverghese/c7f6971b0418ed55a3dc to your computer and use it in GitHub Desktop.

Revisions

  1. ajayverghese revised this gist Apr 1, 2015. 1 changed file with 37 additions and 31 deletions.
    68 changes: 37 additions & 31 deletions gcs_price_calculator.py
    Original file line number Diff line number Diff line change
    @@ -27,35 +27,34 @@ def enum(**named_values):
    XML_GET_OBJECT='XML GET object',
    XML_HEAD='XML HEAD',

    INSERT='insert',
    PATCH='patch',
    UPDATE='update',
    BUCKET_LIST='bucket_list',
    OBJECT_COMPOSE='object_compose',
    OBJECT_COPY='object_copy',
    OBJECT_LIST='object_list',
    OBJECT_WATCHALL='object_watchall',
    BUCKET_ACL_DELETE='bucket_acl_delete',
    DEFAULT_OBJECT_ACL_DELETE='default_object_acl_delete',
    OBJECT_ACL_DELETE='object_acl_delete',
    GET='get',
    BUCKET_ACL_LIST='bucket_acl_list',
    DEFAULT_OBJECT_ACL_LIST='default_object_acl_list',
    OBJECT_ACL_LIST='object_acl_list',
    NOTIFICATION='notification',
    INSERT='Insert',
    PATCH='Patch',
    UPDATE='Update',
    BUCKET_LIST='Bucket list',
    OBJECT_COMPOSE='Object compose',
    OBJECT_COPY='Object copy',
    OBJECT_LIST='Object list',
    OBJECT_WATCHALL='Object watchall',
    BUCKET_ACL_DELETE='Bucket ACL delete',
    DEFAULT_OBJECT_ACL_DELETE='Default object ACL delete',
    OBJECT_ACL_DELETE='Object ACL delete',
    GET='Get',
    BUCKET_ACL_LIST='Bucket ACL list',
    DEFAULT_OBJECT_ACL_LIST='Default object ACL list',
    OBJECT_ACL_LIST='Object ACL list',
    NOTIFICATION='Notification',
    )

    NETWORK_LOCATION = enum(
    CHINA='China',
    AUSTRALIA='Australia',
    WORLDWIDE='All location except China and Australia'
    WORLDWIDE='All locations except China and Australia'
    )


    ############################
    # Calculation parameters - update this with approximates


    DATA_STORED = {
    STORAGE_TYPE.STANDARD: 60 * TB,
    }
    @@ -65,8 +64,9 @@ def enum(**named_values):
    STORAGE_OPERATION.XML_HEAD: 10000000
    }

    # network ingress is free. only egress is charged
    NETWORK_USAGE = {
    NETWORK_LOCATION.WORLDWIDE: 25 * TB,
    NETWORK_LOCATION.WORLDWIDE: 24 * TB,
    NETWORK_LOCATION.CHINA: 25 * TB
    }

    @@ -95,26 +95,32 @@ def enum(**named_values):
    STORAGE_OPERATION.XML_GET_BUCKET_LIST: OPERATION_PRICING['A'],
    STORAGE_OPERATION.XML_PUT: OPERATION_PRICING['A'],
    STORAGE_OPERATION.XML_POST: OPERATION_PRICING['A'],

    STORAGE_OPERATION.INSERT: OPERATION_PRICING['A'],
    STORAGE_OPERATION.PATCH: OPERATION_PRICING['A'],
    STORAGE_OPERATION.UPDATE: OPERATION_PRICING['A'],

    STORAGE_OPERATION.BUCKET_LIST: OPERATION_PRICING['A'],
    STORAGE_OPERATION.BUCKET_ACL_DELETE: OPERATION_PRICING['A'],

    STORAGE_OPERATION.OBJECT_COMPOSE: OPERATION_PRICING['A'],
    STORAGE_OPERATION.OBJECT_COPY: OPERATION_PRICING['A'],
    STORAGE_OPERATION.OBJECT_LIST: OPERATION_PRICING['A'],
    STORAGE_OPERATION.OBJECT_WATCHALL: OPERATION_PRICING['A'],
    STORAGE_OPERATION.BUCKET_ACL_DELETE: OPERATION_PRICING['A'],
    STORAGE_OPERATION.DEFAULT_OBJECT_ACL_DELETE: OPERATION_PRICING['A'],
    STORAGE_OPERATION.OBJECT_ACL_DELETE: OPERATION_PRICING['A'],
    STORAGE_OPERATION.DEFAULT_OBJECT_ACL_DELETE: OPERATION_PRICING['A'],

    # Class B operations
    STORAGE_OPERATION.XML_GET_BUCKET: OPERATION_PRICING['B'],
    STORAGE_OPERATION.XML_GET_OBJECT: OPERATION_PRICING['B'],
    STORAGE_OPERATION.XML_HEAD: OPERATION_PRICING['B'],

    STORAGE_OPERATION.GET: OPERATION_PRICING['B'],
    STORAGE_OPERATION.NOTIFICATION: OPERATION_PRICING['B'],

    STORAGE_OPERATION.BUCKET_ACL_LIST: OPERATION_PRICING['B'],
    STORAGE_OPERATION.DEFAULT_OBJECT_ACL_LIST: OPERATION_PRICING['B'],
    STORAGE_OPERATION.OBJECT_ACL_LIST: OPERATION_PRICING['B'],
    STORAGE_OPERATION.NOTIFICATION: OPERATION_PRICING['B'],
    STORAGE_OPERATION.DEFAULT_OBJECT_ACL_LIST: OPERATION_PRICING['B'],
    }

    # cost for network egress - TB slabs. Cost is per GB
    @@ -166,22 +172,22 @@ def main():
    for op in OPS_USAGE:
    ops_cost += OPS_USAGE[op] * (STORAGE_OPERATION_PRICING[op]['cost'] / STORAGE_OPERATION_PRICING[op]['ops'])


    print 'Usage summary ---'
    print ' STORAGE'
    for storage in DATA_STORED:
    print ' %s: %5.2fGB' % (storage, (DATA_STORED[storage] / GB))
    print ' OPS'
    for op in OPS_USAGE:
    print ' %s: %dops' % (op, OPS_USAGE[op])
    print ' %s: %d ops' % (op, OPS_USAGE[op])
    print ' NETWORK'
    for nw in NETWORK_USAGE:
    print ' Network egress: %.2fTB in %s' % ((NETWORK_USAGE[nw] / TB), nw)
    print ' Network egress: %.2fGB (%s)' % ((NETWORK_USAGE[nw] / GB), nw)

    print '\n\nPricing report ---'
    print 'Cost to store data = $%8.3s' % storage_cost
    print 'Cost due to ops = $%8.3s' % ops_cost
    print 'Cost due to n/w = $%8.3f' % nw_egress_cost
    print 'Total cost = $%8.3f' % (storage_cost + ops_cost + nw_egress_cost)

    print ' Cost to store data = $%8.3f' % storage_cost
    print ' Cost due to ops = $%8.3f' % ops_cost
    print ' Cost due to n/w = $%8.3f' % nw_egress_cost
    print ' Total cost = $%8.3f' % (storage_cost + ops_cost + nw_egress_cost)

    main()
    main()
  2. ajayverghese created this gist Mar 31, 2015.
    187 changes: 187 additions & 0 deletions gcs_price_calculator.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,187 @@
    #!/usr/bin/env python

    '''
    Calculate price for GCS usage
    Prices as on Mar 31 2015 [https://cloud.google.com/storage/pricing]
    '''

    def enum(**named_values):
    return type('Enum', (), named_values)

    MB = 1024 * 1024 * 1.0
    GB = MB * 1024
    TB = GB * 1024

    STORAGE_TYPE = enum(
    STANDARD='Standard storage',
    DRA='Durable reduced availability',
    NEARLINE='Nearline',
    )

    STORAGE_OPERATION = enum(
    XML_GET_SERVICE='XML GET service',
    XML_GET_BUCKET_LIST='XML GET bucket list',
    XML_PUT='XML PUT',
    XML_POST='XML POST',
    XML_GET_BUCKET='XML GET bucket',
    XML_GET_OBJECT='XML GET object',
    XML_HEAD='XML HEAD',

    INSERT='insert',
    PATCH='patch',
    UPDATE='update',
    BUCKET_LIST='bucket_list',
    OBJECT_COMPOSE='object_compose',
    OBJECT_COPY='object_copy',
    OBJECT_LIST='object_list',
    OBJECT_WATCHALL='object_watchall',
    BUCKET_ACL_DELETE='bucket_acl_delete',
    DEFAULT_OBJECT_ACL_DELETE='default_object_acl_delete',
    OBJECT_ACL_DELETE='object_acl_delete',
    GET='get',
    BUCKET_ACL_LIST='bucket_acl_list',
    DEFAULT_OBJECT_ACL_LIST='default_object_acl_list',
    OBJECT_ACL_LIST='object_acl_list',
    NOTIFICATION='notification',
    )

    NETWORK_LOCATION = enum(
    CHINA='China',
    AUSTRALIA='Australia',
    WORLDWIDE='All location except China and Australia'
    )


    ############################
    # Calculation parameters - update this with approximates


    DATA_STORED = {
    STORAGE_TYPE.STANDARD: 60 * TB,
    }

    OPS_USAGE = {
    STORAGE_OPERATION.XML_PUT: 100000,
    STORAGE_OPERATION.XML_HEAD: 10000000
    }

    NETWORK_USAGE = {
    NETWORK_LOCATION.WORLDWIDE: 25 * TB,
    NETWORK_LOCATION.CHINA: 25 * TB
    }

    #############################


    # From
    # https://cloud.google.com/storage/pricing

    # cost per GB
    STORAGE_TYPE_PRICING = {
    STORAGE_TYPE.STANDARD: 0.026,
    STORAGE_TYPE.DRA: 0.02,
    STORAGE_TYPE.NEARLINE: 0.01
    }

    OPERATION_PRICING = {
    'A': {'cost': 0.01, 'ops': 1000},
    'B': {'cost': 0.01, 'ops': 10000}
    }

    # cost for operations
    STORAGE_OPERATION_PRICING = {
    # Class A operations
    STORAGE_OPERATION.XML_GET_SERVICE: OPERATION_PRICING['A'],
    STORAGE_OPERATION.XML_GET_BUCKET_LIST: OPERATION_PRICING['A'],
    STORAGE_OPERATION.XML_PUT: OPERATION_PRICING['A'],
    STORAGE_OPERATION.XML_POST: OPERATION_PRICING['A'],
    STORAGE_OPERATION.INSERT: OPERATION_PRICING['A'],
    STORAGE_OPERATION.PATCH: OPERATION_PRICING['A'],
    STORAGE_OPERATION.UPDATE: OPERATION_PRICING['A'],
    STORAGE_OPERATION.BUCKET_LIST: OPERATION_PRICING['A'],
    STORAGE_OPERATION.OBJECT_COMPOSE: OPERATION_PRICING['A'],
    STORAGE_OPERATION.OBJECT_COPY: OPERATION_PRICING['A'],
    STORAGE_OPERATION.OBJECT_LIST: OPERATION_PRICING['A'],
    STORAGE_OPERATION.OBJECT_WATCHALL: OPERATION_PRICING['A'],
    STORAGE_OPERATION.BUCKET_ACL_DELETE: OPERATION_PRICING['A'],
    STORAGE_OPERATION.DEFAULT_OBJECT_ACL_DELETE: OPERATION_PRICING['A'],
    STORAGE_OPERATION.OBJECT_ACL_DELETE: OPERATION_PRICING['A'],
    # Class B operations
    STORAGE_OPERATION.XML_GET_BUCKET: OPERATION_PRICING['B'],
    STORAGE_OPERATION.XML_GET_OBJECT: OPERATION_PRICING['B'],
    STORAGE_OPERATION.XML_HEAD: OPERATION_PRICING['B'],
    STORAGE_OPERATION.GET: OPERATION_PRICING['B'],
    STORAGE_OPERATION.BUCKET_ACL_LIST: OPERATION_PRICING['B'],
    STORAGE_OPERATION.DEFAULT_OBJECT_ACL_LIST: OPERATION_PRICING['B'],
    STORAGE_OPERATION.OBJECT_ACL_LIST: OPERATION_PRICING['B'],
    STORAGE_OPERATION.NOTIFICATION: OPERATION_PRICING['B'],
    }

    # cost for network egress - TB slabs. Cost is per GB
    NETWORK_EGRESS_PRICING = {
    NETWORK_LOCATION.WORLDWIDE: {
    '1': 0.12, # upto 1TB
    '9': 0.11, # upto 10TB
    '>10': 0.08 # greater than 10TB
    },
    NETWORK_LOCATION.CHINA: {
    '1': 0.23, # upto 1TB
    '9': 0.22, # upto 10TB
    '>10': 0.20 # greater than 10TB
    },
    NETWORK_LOCATION.AUSTRALIA: {
    '1': 0.19, # upto 1TB
    '9': 0.18, # upto 10TB
    '>10': 0.15 # greater than 10TB
    }
    }


    def main():
    # total cost = network_egress + storage_type + storage_operation
    nw_egress_cost = 0
    storage_cost = 0
    ops_cost = 0

    # calculate network charges
    for nw in NETWORK_USAGE:
    regional_cost = 0
    usage = NETWORK_USAGE[nw]
    for slab in [1, 9]:
    regional_cost += (slab * 1024) * NETWORK_EGRESS_PRICING[nw][str(slab)]
    if usage > (slab * TB):
    usage -= (slab * TB)
    else:
    usage = 0
    # highest slab
    if NETWORK_USAGE[nw] > (10 * TB):
    regional_cost += (usage / GB) * NETWORK_EGRESS_PRICING[nw]['>10']
    nw_egress_cost += regional_cost

    # calculate storage charges
    for data in DATA_STORED:
    storage_cost += (DATA_STORED[data] / GB) * STORAGE_TYPE_PRICING[data]

    # calculate ops based charges
    for op in OPS_USAGE:
    ops_cost += OPS_USAGE[op] * (STORAGE_OPERATION_PRICING[op]['cost'] / STORAGE_OPERATION_PRICING[op]['ops'])

    print 'Usage summary ---'
    print ' STORAGE'
    for storage in DATA_STORED:
    print ' %s: %5.2fGB' % (storage, (DATA_STORED[storage] / GB))
    print ' OPS'
    for op in OPS_USAGE:
    print ' %s: %dops' % (op, OPS_USAGE[op])
    print ' NETWORK'
    for nw in NETWORK_USAGE:
    print ' Network egress: %.2fTB in %s' % ((NETWORK_USAGE[nw] / TB), nw)

    print '\n\nPricing report ---'
    print 'Cost to store data = $%8.3s' % storage_cost
    print 'Cost due to ops = $%8.3s' % ops_cost
    print 'Cost due to n/w = $%8.3f' % nw_egress_cost
    print 'Total cost = $%8.3f' % (storage_cost + ops_cost + nw_egress_cost)


    main()