Skip to content

Commit d6641a9

Browse files
authored
[UI] support Postgres version and pod resource changes + adding IOPS and throughput config options (zalando#1824)
1 parent 654d22d commit d6641a9

File tree

7 files changed

+137
-14
lines changed

7 files changed

+137
-14
lines changed

ui/app/src/edit.tag.pug

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ edit
126126
if (i.metadata.selfLink) { delete i.metadata.selfLink }
127127
if (i.metadata.uid) { delete i.metadata.uid }
128128
if (i.metadata.resourceVersion) { delete i.metadata.resourceVersion }
129+
if (i.metadata.managedFields) { delete i.metadata.managedFields }
129130

130131
this.update()
131132
this.refs.yamlNice.innerHTML = yamlParser.safeDump(i.postgresql, {sortKeys: true})
@@ -138,7 +139,15 @@ edit
138139
o.spec.enableMasterLoadBalancer = i.spec.enableMasterLoadBalancer || false
139140
o.spec.enableReplicaLoadBalancer = i.spec.enableReplicaLoadBalancer || false
140141
o.spec.enableConnectionPooler = i.spec.enableConnectionPooler || false
141-
o.spec.volume = { size: i.spec.volume.size }
142+
143+
o.spec.volume = {
144+
size: i.spec.volume.size,
145+
throughput: i.spec.volume.throughput || 125,
146+
iops: i.spec.volume.iops || 3000
147+
}
148+
149+
o.spec.postgresql = {}
150+
o.spec.postgresql.version = i.spec.postgresql.version
142151

143152
if ('users' in i.spec && typeof i.spec.users === 'object') {
144153
o.spec.users = Object.mapValues(i.spec.users, roleFlags =>
@@ -166,7 +175,7 @@ edit
166175
].forEach(resourceType => {
167176
if (resourceType in resources) {
168177
const resourceClaim = resources[resourceType]
169-
if (typeof resourceClaim === '') {
178+
if (typeof resourceClaim === 'string') {
170179
o.spec.resources[section][resourceType] = resources[resourceType]
171180
}
172181
}

ui/app/src/help-general.tag.pug

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ help-general
1313
h3 Basics
1414

1515
p.
16-
The PostgreSQL operator will use your definition to create a new
16+
The Postgres Operator will use your definition to create a new
1717
PostgreSQL cluster for you. You can either copy the yaml definition
18-
to the repositiory or you can just hit create cluster.
18+
to a repositiory or hit create cluster (not available in prod).

ui/app/src/new.tag.pug

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,37 @@ new
266266
)
267267
.input-group-addon
268268
.input-units Gi
269+
tr
270+
td
271+
td Specify Iops and Throughput only if you need more than the default 3000 Iops and 125Mb/s EBS provides.
272+
273+
tr
274+
td Iops
275+
td
276+
.input-group
277+
input.form-control(
278+
ref='iops'
279+
type='number'
280+
value='{ iops }'
281+
onchange='{ iopsChange }'
282+
onkeyup='{ iopsChange }'
283+
)
284+
.input-group-addon
285+
.input-units
286+
287+
tr
288+
td Througput
289+
td
290+
.input-group
291+
input.form-control(
292+
ref='throughput'
293+
type='number'
294+
value='{ throughput }'
295+
onchange='{ throughputChange }'
296+
onkeyup='{ throughputChange }'
297+
)
298+
.input-group-addon
299+
.input-units MB/s
269300

270301
tr(if='{ config.users_visible }')
271302
td
@@ -509,7 +540,9 @@ new
509540
enableConnectionPooler: true
510541
{{/if}}
511542
volume:
512-
size: "{{ volumeSize }}Gi"
543+
size: "{{ volumeSize }}Gi"{{#if iops}}
544+
iops: {{ iops }}{{/if}}{{#if throughput}}
545+
throughput: {{ throughput }}{{/if}}
513546
{{#if users}}
514547
users:{{#each users}}
515548
{{ state }}: []{{/each}}{{/if}}
@@ -560,6 +593,8 @@ new
560593
enableReplicaLoadBalancer: this.enableReplicaLoadBalancer,
561594
enableConnectionPooler: this.enableConnectionPooler,
562595
volumeSize: this.volumeSize,
596+
iops: this.iops,
597+
throughput: this.throughput,
563598
users: this.users.valids,
564599
databases: this.databases.valids,
565600
ranges: this.ranges,
@@ -624,6 +659,14 @@ new
624659
this.volumeSize = +e.target.value
625660
}
626661

662+
this.iopsChange = e => {
663+
this.iops = +e.target.value
664+
}
665+
666+
this.throughputChange = e => {
667+
this.throughput = +e.target.value
668+
}
669+
627670
this.updateDNSName = () => {
628671
this.dnsName = this.config.dns_format_string.format(
629672
this.name,

ui/app/src/postgresqls.tag.pug

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ postgresqls
6969
td { cpu } / { cpu_limit }
7070
td { memory } / { memory_limit }
7171
td { volume_size }
72-
td { calcCosts(nodes, cpu, memory, volume_size) }$
72+
td { calcCosts(nodes, cpu, memory, volume_size, iops, throughput) }$
7373

7474
td
7575

@@ -152,7 +152,7 @@ postgresqls
152152
td { cpu } / { cpu_limit }
153153
td { memory } / { memory_limit }
154154
td { volume_size }
155-
td { calcCosts(nodes, cpu, memory, volume_size) }$
155+
td { calcCosts(nodes, cpu, memory, volume_size, iops, throughput) }$
156156

157157
td
158158

@@ -227,9 +227,22 @@ postgresqls
227227
+ '/' + encodeURI(cluster.name)
228228
)
229229

230-
const calcCosts = this.calcCosts = (nodes, cpu, memory, disk) => {
231-
costs = Math.max(nodes, opts.config.min_pods) * (toCores(cpu) * opts.config.cost_core + toMemory(memory) * opts.config.cost_memory + toDisk(disk) * opts.config.cost_ebs)
232-
return costs.toFixed(2)
230+
const calcCosts = this.calcCosts = (nodes, cpu, memory, disk, iops, throughput) => {
231+
podcount = Math.max(nodes, opts.config.min_pods)
232+
corecost = toCores(cpu) * opts.config.cost_core
233+
memorycost = toMemory(memory) * opts.config.cost_memory
234+
diskcost = toDisk(disk) * opts.config.cost_ebs
235+
iopscost = 0
236+
if (iops !== undefined && iops > 3000) {
237+
iopscost = (iops - 3000) * opts.config.cost_iops
238+
}
239+
throughputcost = 0
240+
if (throughput !== undefined && throughput > 125) {
241+
throughputcost = (throughput - 125) * opts.config.cost_throughput
242+
}
243+
244+
costs = podcount * (corecost + memorycost + diskcost + iopscost + throughputcost)
245+
return costs.toFixed(2)
233246
}
234247

235248
const toDisk = this.toDisk = value => {
@@ -253,6 +266,11 @@ postgresqls
253266
value = Number(value)
254267
return value
255268
}
269+
else if(value.endsWith("Ti")) {
270+
value = value.substring(0, value.length-2)
271+
value = Number(value) * 1000
272+
return value
273+
}
256274

257275
return value
258276
}

ui/manifests/deployment.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ spec:
6262
"replica_load_balancer_visible": true,
6363
"resources_visible": true,
6464
"users_visible": true,
65-
"cost_ebs": 0.119,
65+
"cost_ebs": 0.0952,
66+
"cost_iops": 0.006,
67+
"cost_throughput": 0.0476,
6668
"cost_core": 0.0575,
6769
"cost_memory": 0.014375,
6870
"postgresql_versions": [

ui/operator_ui/main.py

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,10 @@
8989
GOOGLE_ANALYTICS = getenv('GOOGLE_ANALYTICS', False)
9090
MIN_PODS= getenv('MIN_PODS', 2)
9191

92-
# storage pricing, i.e. https://aws.amazon.com/ebs/pricing/
93-
COST_EBS = float(getenv('COST_EBS', 0.119)) # GB per month
92+
# storage pricing, i.e. https://aws.amazon.com/ebs/pricing/ (e.g. Europe - Franfurt)
93+
COST_EBS = float(getenv('COST_EBS', 0.0952)) # GB per month
94+
COST_IOPS = float(getenv('COST_IOPS', 0.006)) # IOPS per month above 3000 baseline
95+
COST_THROUGHPUT = float(getenv('COST_THROUGHPUT', 0.0476)) # MB/s per month above 125 MB/s baseline
9496

9597
# compute costs, i.e. https://www.ec2instances.info/?region=eu-central-1&selected=m5.2xlarge
9698
COST_CORE = 30.5 * 24 * float(getenv('COST_CORE', 0.0575)) # Core per hour m5.2xlarge / 8.
@@ -308,6 +310,8 @@ def index():
308310
'pgui_link': '',
309311
'static_network_whitelist': {},
310312
'cost_ebs': COST_EBS,
313+
'cost_iops': COST_IOPS,
314+
'cost_throughput': COST_THROUGHPUT,
311315
'cost_core': COST_CORE,
312316
'cost_memory': COST_MEMORY,
313317
'min_pods': MIN_PODS
@@ -487,6 +491,8 @@ def get_postgresqls():
487491
'cpu': spec.get('resources', {}).get('requests', {}).get('cpu', 0),
488492
'cpu_limit': spec.get('resources', {}).get('limits', {}).get('cpu', 0),
489493
'volume_size': spec.get('volume', {}).get('size', 0),
494+
'iops': spec.get('volume', {}).get('iops', 3000),
495+
'throughput': spec.get('volume', {}).get('throughput', 125),
490496
'team': (
491497
spec.get('teamId') or
492498
metadata.get('labels', {}).get('team', '')
@@ -614,6 +620,28 @@ def update_postgresql(namespace: str, cluster: str):
614620

615621
spec['volume'] = {'size': size}
616622

623+
if (
624+
'volume' in postgresql['spec']
625+
and 'iops' in postgresql['spec']['volume']
626+
and postgresql['spec']['volume']['iops'] != None
627+
):
628+
iops = int(postgresql['spec']['volume']['iops'])
629+
if not 'volume' in spec:
630+
spec['volume'] = {}
631+
632+
spec['volume']['iops'] = iops
633+
634+
if (
635+
'volume' in postgresql['spec']
636+
and 'throughput' in postgresql['spec']['volume']
637+
and postgresql['spec']['volume']['throughput'] != None
638+
):
639+
throughput = int(postgresql['spec']['volume']['throughput'])
640+
if not 'volume' in spec:
641+
spec['volume'] = {}
642+
643+
spec['volume']['throughput'] = throughput
644+
617645
if 'enableConnectionPooler' in postgresql['spec']:
618646
cp = postgresql['spec']['enableConnectionPooler']
619647
if not cp:
@@ -758,6 +786,27 @@ def update_postgresql(namespace: str, cluster: str):
758786
owner_username=owner_username,
759787
)
760788

789+
resource_types = ["cpu","memory"]
790+
resource_constraints = ["requests","limits"]
791+
if "resources" in postgresql["spec"]:
792+
spec["resources"] = {}
793+
794+
res = postgresql["spec"]["resources"]
795+
for rt in resource_types:
796+
for rc in resource_constraints:
797+
if rc in res:
798+
if rt in res[rc]:
799+
if not rc in spec["resources"]:
800+
spec["resources"][rc] = {}
801+
spec["resources"][rc][rt] = res[rc][rt]
802+
803+
if "postgresql" in postgresql["spec"]:
804+
if "version" in postgresql["spec"]["postgresql"]:
805+
if "postgresql" not in spec:
806+
spec["postgresql"]={}
807+
808+
spec["postgresql"]["version"] = postgresql["spec"]["postgresql"]["version"]
809+
761810
o['spec'].update(spec)
762811

763812
apply_postgresql(get_cluster(), namespace, cluster, o)

ui/run_local.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ default_operator_ui_config='{
1919
"nat_gateways_visible": false,
2020
"resources_visible": true,
2121
"users_visible": true,
22-
"cost_ebs": 0.119,
22+
"cost_ebs": 0.0952,
23+
"cost_iops": 0.006,
24+
"cost_throughput": 0.0476,
2325
"cost_core": 0.0575,
2426
"cost_memory": 0.014375,
2527
"postgresql_versions": [

0 commit comments

Comments
 (0)