def ds_pricing(reads=30000, writes=20000, storage=100, scale=0.0, ctype='multi-region', disc_factor=app_defaults.get()['ds_discount_factor']): params = app_defaults.get() inputs = { 'reads': reads, 'writes': writes, 'storage': storage, 'scale': scale, 'ctype': ctype, 'disc_factor': disc_factor } params.update(inputs) return ds_pricing(params)
def ds_pricing(inputs): # refactor ctype = inputs['ctype'] ctypes = conf_datastore.get().keys() # ['single-region', 'multi-region'] # if not provided or if invalid, select default if ctype is not None and ctype not in ctypes: ctype = ctypes[1] # issue warning? / default to multi # bs price config cfg = conf_datastore.get()[ctype] data = {} app.logger.debug('DS PRICING: CFG:{}'.format(json.dumps(cfg, indent=2))) app.logger.debug('DS INPUTS: CFG:{}'.format( json.dumps(inputs['disc_factor'], indent=2))) data = scale_data(data, inputs) # push config into data data.update(cfg) #validate sub discounts refactor app.logger.debug('TYPE DISCOUNT: {}'.format(type(inputs['disc_factor']))) if type(inputs['disc_factor']) is not dict: inputs['disc_factor'] = app_defaults.get()['ds_discount_factor'] data['storage_cost'] = data['storage_base_cost'] * data[ 'storage'] * 1024 # TB to GB data['discounted_storage_cost'] = data['storage_cost'] * inputs[ 'disc_factor']['storage'] #adjust freebies, using 30 days ... data['monthly_reads'] = data['reads'] * globals['seconds_to_month'] - ( 30 * cfg['platform']['free_reads']) data['monthly_writes'] = data['writes'] * globals['seconds_to_month'] - ( 30 * cfg['platform']['free_writes']) data['monthly_deletes'] = max( 0, data['deletes'] * globals['seconds_to_month'] - (30 * cfg['platform']['free_deletes'])) #READS # default data['read_cost'] = data['monthly_reads'] / data['io_unit'] * data[ 'read_base_cost'] #adjust tiered discount -- almost always over 50K per day. if data['monthly_reads'] > data['tier1_cap'] * data['io_unit']: data['read_cost_tier1'] = data['tier1_cap'] * data['read_base_cost'] data['read_cost_tier2'] = (data['monthly_reads'] / data['io_unit'] - data['tier1_cap']) * data['read_base_cost'] data['read_cost'] = data['read_cost_tier1'] + data['read_cost_tier2'] # if discount...(default is 1) data['discounted_read_cost'] = data['read_cost'] * inputs['disc_factor'][ 'reads'] # WRITES data['write_cost'] = data['monthly_writes'] / data['io_unit'] * data[ 'write_base_cost'] data['discounted_write_cost'] = data['write_cost'] * inputs['disc_factor'][ 'writes'] # DELETES data['delete_cost'] = data['monthly_deletes'] / data['io_unit'] * data[ 'delete_base_cost'] ### fix me data['discounted_delete_cost'] = data['delete_cost'] * inputs[ 'disc_factor']['deletes'] # TOTAL IO data['io_cost'] = data['read_cost'] + data['write_cost'] + data[ 'delete_cost'] data['discounted_io_cost'] = data['discounted_read_cost'] + data[ 'discounted_write_cost'] + data['discounted_delete_cost'] # TOTAL COSTS data['total_cost'] = data['io_cost'] + data['storage_cost'] data['total_discounted_cost'] = data['discounted_io_cost'] + data[ 'discounted_storage_cost'] format_data(data) output = { 'inputs': inputs, 'globals': globals, 'data': data, 'config': cfg } return output
def __def_spanner_pricing(): return spanner_pricing(app_defaults.get())
def __def_ds_pricing(): return ds_pricing(app_defaults.get())
def __def_bt_pricing(): return bt_pricing(app_defaults.get())
def lp_json_conf(): # default input cfg = app_defaults.get() app.logger.info('App Defaults: {}'.format(cfg)) # receive json input input_json = request.data app.logger.info('Posted Input: {}'.format(input_json)) app.logger.debug(input_json, type(input_json)) if input_json: json_input = json.loads(input_json) app.logger.info('Form Input:\n{}'.format( json.dumps(json_input, indent=2))) cfg.update(json_input) # function driver table measures = { 'Datastore Multi': { 'ctype': 'multi-region', 'discount': 'ds_discount_factor', 'funcname': ds_pricing, 'stype': 'ssd' }, 'Datastore Single': { 'ctype': 'single-region', 'discount': 'ds_discount_factor', 'funcname': ds_pricing, 'stype': 'ssd' }, 'Bigtable Multi Replication': { 'ctype': 'repl-multi', 'discount': 'bt_discount_factor', 'funcname': bt_pricing, 'stype': 'ssd' }, 'Bigtable Single Replication': { 'ctype': 'repl-single', 'discount': 'bt_discount_factor', 'funcname': bt_pricing, 'stype': 'ssd' }, 'Bigtable Single SSD': { 'ctype': 'single', 'discount': 'bt_discount_factor', 'funcname': bt_pricing, 'stype': 'ssd' }, 'Bigtable Single HDD': { 'ctype': 'single', 'discount': 'bt_discount_factor', 'funcname': bt_pricing, 'stype': 'hdd' }, 'Spanner Multi': { 'ctype': 'multi', 'discount': 'spanner_discount_factor', 'funcname': spanner_pricing, 'stype': 'ssd' }, 'Spanner Single': { 'ctype': 'single', 'discount': 'spanner_discount_factor', 'funcname': spanner_pricing, 'stype': 'ssd' }, 'Spanner Global': { 'ctype': 'global', 'discount': 'spanner_discount_factor', 'funcname': spanner_pricing, 'stype': 'ssd' }, 'Cloud SQL Postgresql': { 'ctype': 'single', 'discount': 'sql_discount_factor', 'funcname': sql_pricing, 'stype': 'ssd' } } #app.logger.info('Executions: {}'.format(measures)) output = {} for k, v in measures.items(): app.logger.debug('calc on :\n{}'.format(json.dumps(k, indent=2))) # refactor -- but selecting which discount use, currently flat,needs to 1:set -- # (done but needs to shift left) # function name effectively carries the discount var key ... cfg['disc_factor'] = cfg[v['discount']] cfg.update(v) #merge # set output key to deference to function, pass in merged config output[k] = v['funcname'](cfg)['data'] # removal flags this removes cloud sql if passed capacity (i.e. 100TB storage in PostGres) if any(x in ['EXCEEDS_TPS_CAPACITY', 'STORAGE_EXCEEDED'] for x in output[k]): del output[k] return output