[UI] include load balancer in the monthly cost calculation (#1977)

This commit is contained in:
idanovinda 2022-10-26 12:19:48 +02:00 committed by GitHub
parent 529cdfc0b6
commit 18908e6097
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 131 additions and 81 deletions

View File

@ -139,6 +139,9 @@ edit
o.spec.enableMasterLoadBalancer = i.spec.enableMasterLoadBalancer || false o.spec.enableMasterLoadBalancer = i.spec.enableMasterLoadBalancer || false
o.spec.enableReplicaLoadBalancer = i.spec.enableReplicaLoadBalancer || false o.spec.enableReplicaLoadBalancer = i.spec.enableReplicaLoadBalancer || false
o.spec.enableConnectionPooler = i.spec.enableConnectionPooler || false o.spec.enableConnectionPooler = i.spec.enableConnectionPooler || false
o.spec.enableReplicaConnectionPooler = i.spec.enableReplicaConnectionPooler || false
o.spec.enableMasterPoolerLoadBalancer = i.spec.enableMasterPoolerLoadBalancer || false
o.spec.enableReplicaPoolerLoadBalancer = i.spec.enableReplicaPoolerLoadBalancer || false
o.spec.volume = { o.spec.volume = {
size: i.spec.volume.size, size: i.spec.volume.size,

View File

@ -216,40 +216,73 @@ new
) )
tr(if='{ [undefined, true].includes(config.master_load_balancer_visible) }') tr(if='{ [undefined, true].includes(config.master_load_balancer_visible) }')
td Master load balancer td Enable load balancer
td td
label ul.ips
input( li
type='checkbox' label
value='{ enableMasterLoadBalancer }' input(
onchange='{ toggleEnableMasterLoadBalancer }' type='checkbox'
) value='{ enableMasterLoadBalancer }'
| onchange='{ toggleEnableMasterLoadBalancer }'
| Enable master ELB )
|
| Master
li(if='{ [undefined, true].includes(config.replica_load_balancer_visible) && instanceCount > 1 }')
label
input(
type='checkbox'
value='{ enableReplicaLoadBalancer }'
onchange='{ toggleEnableReplicaLoadBalancer }'
)
|
| Replica
tr(if='{ [undefined, true].includes(config.replica_load_balancer_visible) }') tr(if='{ [undefined, true].includes(config.connection_pooler_visible) }')
td Replica load balancer td Enable connection pooler
td td
label ul.ips
input( li
type='checkbox' label
value='{ enableReplicaLoadBalancer }' input(
onchange='{ toggleEnableReplicaLoadBalancer }' type='checkbox'
) value='{ enableConnectionPooler }'
| onchange='{ toggleEnableConnectionPooler }'
| Enable replica ELB )
|
| Master
li(if='{ [undefined, true].includes(config.replica_connection_pooler_visible) && instanceCount > 1 }')
label
input(
type='checkbox'
value='{ enableReplicaConnectionPooler }'
onchange='{ toggleEnableReplicaConnectionPooler }'
)
|
| Replica
tr tr(if='{ [undefined, true].includes(config.master_pooler_load_balancer_visible) }')
td Enable Connection Pool td Enable connection pooler load balancer
td td
label ul.ips
input( li
type='checkbox' label
value='{ enableConnectionPooler }' input(
onchange='{ toggleEnableConnectionPooler }' type='checkbox'
) value='{ enableMasterPoolerLoadBalancer }'
| onchange='{ toggleEnableMasterPoolerLoadBalancer }'
| Enable Connection Pool (using PGBouncer) )
|
| Master
li(if='{ [undefined, true].includes(config.replica_pooler_load_balancer_visible) && instanceCount > 1 }')
label
input(
type='checkbox'
value='{ enableReplicaPoolerLoadBalancer }'
onchange='{ toggleEnableReplicaPoolerLoadBalancer }'
)
|
| Replica
tr tr
td Volume size td Volume size
@ -539,6 +572,15 @@ new
{{#if enableConnectionPooler}} {{#if enableConnectionPooler}}
enableConnectionPooler: true enableConnectionPooler: true
{{/if}} {{/if}}
{{#if enableReplicaConnectionPooler}}
enableReplicaConnectionPooler: true
{{/if}}
{{#if enableMasterPoolerLoadBalancer}}
enableMasterPoolerLoadBalancer: true
{{/if}}
{{#if enableReplicaPoolerLoadBalancer}}
enableReplicaPoolerLoadBalancer: true
{{/if}}
volume: volume:
size: "{{ volumeSize }}Gi"{{#if iops}} size: "{{ volumeSize }}Gi"{{#if iops}}
iops: {{ iops }}{{/if}}{{#if throughput}} iops: {{ iops }}{{/if}}{{#if throughput}}
@ -592,6 +634,9 @@ new
enableMasterLoadBalancer: this.enableMasterLoadBalancer, enableMasterLoadBalancer: this.enableMasterLoadBalancer,
enableReplicaLoadBalancer: this.enableReplicaLoadBalancer, enableReplicaLoadBalancer: this.enableReplicaLoadBalancer,
enableConnectionPooler: this.enableConnectionPooler, enableConnectionPooler: this.enableConnectionPooler,
enableReplicaConnectionPooler: this.enableReplicaConnectionPooler,
enableMasterPoolerLoadBalancer: this.enableMasterPoolerLoadBalancer,
enableReplicaPoolerLoadBalancer: this.enableReplicaPoolerLoadBalancer,
volumeSize: this.volumeSize, volumeSize: this.volumeSize,
iops: this.iops, iops: this.iops,
throughput: this.throughput, throughput: this.throughput,
@ -655,6 +700,18 @@ new
this.enableConnectionPooler = !this.enableConnectionPooler this.enableConnectionPooler = !this.enableConnectionPooler
} }
this.toggleEnableReplicaConnectionPooler = e => {
this.enableReplicaConnectionPooler = !this.enableReplicaConnectionPooler
}
this.toggleEnableMasterPoolerLoadBalancer = e => {
this.enableMasterPoolerLoadBalancer = !this.enableMasterPoolerLoadBalancer
}
this.toggleEnableReplicaPoolerLoadBalancer = e => {
this.enableReplicaPoolerLoadBalancer = !this.enableReplicaPoolerLoadBalancer
}
this.volumeChange = e => { this.volumeChange = e => {
this.volumeSize = +e.target.value this.volumeSize = +e.target.value
} }
@ -692,6 +749,11 @@ new
this.instanceCountChange = e => { this.instanceCountChange = e => {
this.instanceCount = +e.target.value this.instanceCount = +e.target.value
if (this.instanceCount < 2) {
this.enableReplicaLoadBalancer = false
this.enableReplicaConnectionPooler = false
this.enableReplicaPoolerLoadBalancer = false
}
} }
this.checkClusterExists = () => ( this.checkClusterExists = () => (
@ -957,6 +1019,9 @@ new
this.enableMasterLoadBalancer = false this.enableMasterLoadBalancer = false
this.enableReplicaLoadBalancer = false this.enableReplicaLoadBalancer = false
this.enableConnectionPooler = false this.enableConnectionPooler = false
this.enableReplicaConnectionPooler = false
this.enableMasterPoolerLoadBalancer = false
this.enableReplicaPoolerLoadBalancer = false
this.postgresqlVersion = this.postgresqlVersion = ( this.postgresqlVersion = this.postgresqlVersion = (
this.config.postgresql_versions[0] this.config.postgresql_versions[0]

View File

@ -168,10 +168,12 @@ postgresql
this.progress.dnsName = data.metadata.name + '.' + data.metadata.namespace this.progress.dnsName = data.metadata.name + '.' + data.metadata.namespace
} }
jQuery.get('/pooler/' + this.cluster_path).done(data => { if (this.progress.poolerEnabled == true) {
this.progress.pooler = {"url": ""} jQuery.get('/pooler/' + this.cluster_path).done(data => {
this.update() this.progress.pooler = {"url": ""}
}) this.update()
})
}
this.update() this.update()
}) })

View File

@ -68,6 +68,8 @@ postgresqls
| IOPS (-3000 baseline): 0.006$ | IOPS (-3000 baseline): 0.006$
br br
| Throughput (-125 baseline): 0.0476$ | Throughput (-125 baseline): 0.0476$
br
| 1 ELB: 21.96$
th(stlye='width: 120px') th(stlye='width: 120px')
tbody tbody
@ -87,7 +89,7 @@ postgresqls
td { volume_size } td { volume_size }
td { iops } td { iops }
td { throughput } td { throughput }
td { calcCosts(nodes, cpu, memory, volume_size, iops, throughput) }$ td { calcCosts(nodes, cpu, memory, volume_size, iops, throughput, num_elb) }$
td td
@ -167,7 +169,9 @@ postgresqls
| IOPS (-3000 baseline): 0.006$ | IOPS (-3000 baseline): 0.006$
br br
| Throughput (-125 baseline): 0.0476$ | Throughput (-125 baseline): 0.0476$
th(stlye='width: 120px') br
| 1 ELB: 21.96$
th(style='width: 120px')
tbody tbody
tr( tr(
@ -188,7 +192,7 @@ postgresqls
td { volume_size } td { volume_size }
td { iops } td { iops }
td { throughput } td { throughput }
td { calcCosts(nodes, cpu, memory, volume_size, iops, throughput) }$ td { calcCosts(nodes, cpu, memory, volume_size, iops, throughput, num_elb) }$
td td
@ -263,10 +267,11 @@ postgresqls
+ '/' + encodeURI(cluster.name) + '/' + encodeURI(cluster.name)
) )
const calcCosts = this.calcCosts = (nodes, cpu, memory, disk, iops, throughput) => { const calcCosts = this.calcCosts = (nodes, cpu, memory, disk, iops, throughput, num_elb) => {
podcount = Math.max(nodes, opts.config.min_pods) podcount = Math.max(nodes, opts.config.min_pods)
corecost = toCores(cpu) * opts.config.cost_core * 30.5 * 24 corecost = toCores(cpu) * opts.config.cost_core * 30.5 * 24
memorycost = toMemory(memory) * opts.config.cost_memory * 30.5 * 24 memorycost = toMemory(memory) * opts.config.cost_memory * 30.5 * 24
elbcost = num_elb * opts.config.cost_elb * 30.5 * 24
diskcost = toDisk(disk) * opts.config.cost_ebs diskcost = toDisk(disk) * opts.config.cost_ebs
iopscost = 0 iopscost = 0
if (iops !== undefined && iops > opts.config.free_iops) { if (iops !== undefined && iops > opts.config.free_iops) {
@ -283,7 +288,7 @@ postgresqls
throughputcost = (throughput - opts.config.free_throughput) * opts.config.cost_throughput throughputcost = (throughput - opts.config.free_throughput) * opts.config.cost_throughput
} }
costs = podcount * (Math.max(corecost, memorycost) + diskcost + iopscost + throughputcost) costs = podcount * (Math.max(corecost, memorycost) + diskcost + iopscost + throughputcost) + elbcost
return costs.toFixed(2) return costs.toFixed(2)
} }

View File

@ -101,6 +101,7 @@ COST_THROUGHPUT = float(getenv('COST_THROUGHPUT', 0.0476)) # MB/s per month abo
# compute costs, i.e. https://www.ec2instances.info/?region=eu-central-1&selected=m5.2xlarge # compute costs, i.e. https://www.ec2instances.info/?region=eu-central-1&selected=m5.2xlarge
COST_CORE = float(getenv('COST_CORE', 0.0575)) # Core per hour m5.2xlarge / 8. COST_CORE = float(getenv('COST_CORE', 0.0575)) # Core per hour m5.2xlarge / 8.
COST_MEMORY = float(getenv('COST_MEMORY', 0.014375)) # Memory GB m5.2xlarge / 32. COST_MEMORY = float(getenv('COST_MEMORY', 0.014375)) # Memory GB m5.2xlarge / 32.
COST_ELB = float(getenv('COST_ELB', 0.03)) # per hour
# maximum and limitation of IOPS and throughput # maximum and limitation of IOPS and throughput
FREE_IOPS = float(getenv('FREE_IOPS', 3000)) FREE_IOPS = float(getenv('FREE_IOPS', 3000))
@ -334,6 +335,7 @@ DEFAULT_UI_CONFIG = {
'cost_throughput': COST_THROUGHPUT, 'cost_throughput': COST_THROUGHPUT,
'cost_core': COST_CORE, 'cost_core': COST_CORE,
'cost_memory': COST_MEMORY, 'cost_memory': COST_MEMORY,
'cost_elb': COST_ELB,
'min_pods': MIN_PODS, 'min_pods': MIN_PODS,
'free_iops': FREE_IOPS, 'free_iops': FREE_IOPS,
'free_throughput': FREE_THROUGHPUT, 'free_throughput': FREE_THROUGHPUT,
@ -523,6 +525,8 @@ def get_postgresqls():
'namespaced_name': namespace + '/' + name, 'namespaced_name': namespace + '/' + name,
'full_name': namespace + '/' + name + ('/' + uid if uid else ''), 'full_name': namespace + '/' + name + ('/' + uid if uid else ''),
'status': status, 'status': status,
'num_elb': spec.get('enableMasterLoadBalancer', 0) + spec.get('enableReplicaLoadBalancer', 0) + \
spec.get('enableMasterPoolerLoadBalancer', 0) + spec.get('enableReplicaPoolerLoadBalancer', 0),
} }
for cluster in these( for cluster in these(
read_postgresqls( read_postgresqls(
@ -662,49 +666,20 @@ def update_postgresql(namespace: str, cluster: str):
spec['volume']['throughput'] = throughput spec['volume']['throughput'] = throughput
if 'enableConnectionPooler' in postgresql['spec']: additional_specs = ['enableMasterLoadBalancer',
cp = postgresql['spec']['enableConnectionPooler'] 'enableReplicaLoadBalancer',
if not cp: 'enableConnectionPooler',
if 'enableConnectionPooler' in o['spec']: 'enableReplicaConnectionPooler',
del o['spec']['enableConnectionPooler'] 'enableMasterPoolerLoadBalancer',
else: 'enableReplicaPoolerLoadBalancer',
spec['enableConnectionPooler'] = True ]
else:
if 'enableConnectionPooler' in o['spec']:
del o['spec']['enableConnectionPooler']
if 'enableReplicaConnectionPooler' in postgresql['spec']: for var in additional_specs:
cp = postgresql['spec']['enableReplicaConnectionPooler'] if postgresql['spec'].get(var):
if not cp: spec[var] = True
if 'enableReplicaConnectionPooler' in o['spec']:
del o['spec']['enableReplicaConnectionPooler']
else: else:
spec['enableReplicaConnectionPooler'] = True if var in o['spec']:
else: del o['spec'][var]
if 'enableReplicaConnectionPooler' in o['spec']:
del o['spec']['enableReplicaConnectionPooler']
if 'enableReplicaLoadBalancer' in postgresql['spec']:
rlb = postgresql['spec']['enableReplicaLoadBalancer']
if not rlb:
if 'enableReplicaLoadBalancer' in o['spec']:
del o['spec']['enableReplicaLoadBalancer']
else:
spec['enableReplicaLoadBalancer'] = True
else:
if 'enableReplicaLoadBalancer' in o['spec']:
del o['spec']['enableReplicaLoadBalancer']
if 'enableMasterLoadBalancer' in postgresql['spec']:
rlb = postgresql['spec']['enableMasterLoadBalancer']
if not rlb:
if 'enableMasterLoadBalancer' in o['spec']:
del o['spec']['enableMasterLoadBalancer']
else:
spec['enableMasterLoadBalancer'] = True
else:
if 'enableMasterLoadBalancer' in o['spec']:
del o['spec']['enableMasterLoadBalancer']
if 'users' in postgresql['spec']: if 'users' in postgresql['spec']:
spec['users'] = postgresql['spec']['users'] spec['users'] = postgresql['spec']['users']