Skip to content

Commit 6268fb8

Browse files
authored
update column and cost function (zalando#1894)
1 parent 97be5ee commit 6268fb8

File tree

4 files changed

+151
-22
lines changed

4 files changed

+151
-22
lines changed

ui/app/src/postgresqls.tag.pug

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,23 @@ postgresqls
5151
th(style='width: 140px') CPU
5252
th(style='width: 130px') Memory
5353
th(style='width: 100px') Size
54-
th(style='width: 120px') Cost/Month
54+
th(style='width: 100px') IOPS
55+
th(style='width: 100px') Throughput
56+
th(style='width: 120px')
57+
.tooltip(style='width: 120px')
58+
| Cost/Month
59+
.tooltiptext
60+
strong Cost = MAX(CPU, Memory) + rest
61+
br
62+
| 1 CPU core : 42.09$
63+
br
64+
| 1GB memory: 10.5225$
65+
br
66+
| 1GB volume: 0.0952$
67+
br
68+
| IOPS (-3000 baseline): 0.006$
69+
br
70+
| Throughput (-125 baseline): 0.0476$
5571
th(stlye='width: 120px')
5672

5773
tbody
@@ -69,6 +85,8 @@ postgresqls
6985
td { cpu } / { cpu_limit }
7086
td { memory } / { memory_limit }
7187
td { volume_size }
88+
td { iops }
89+
td { throughput }
7290
td { calcCosts(nodes, cpu, memory, volume_size, iops, throughput) }$
7391

7492
td
@@ -132,7 +150,23 @@ postgresqls
132150
th(style='width: 140px') CPU
133151
th(style='width: 130px') Memory
134152
th(style='width: 100px') Size
135-
th(style='width: 120px') Cost/Month
153+
th(style='width: 100px') IOPS
154+
th(style='width: 100px') Throughput
155+
th(style='width: 120px')
156+
.tooltip(style='width: 120px')
157+
| Cost/Month
158+
.tooltiptext
159+
strong Cost = MAX(CPU, Memory) + rest
160+
br
161+
| 1 CPU core : 42.09$
162+
br
163+
| 1GB memory: 10.5225$
164+
br
165+
| 1GB volume: 0.0952$
166+
br
167+
| IOPS (-3000 baseline): 0.006$
168+
br
169+
| Throughput (-125 baseline): 0.0476$
136170
th(stlye='width: 120px')
137171

138172
tbody
@@ -152,6 +186,8 @@ postgresqls
152186
td { cpu } / { cpu_limit }
153187
td { memory } / { memory_limit }
154188
td { volume_size }
189+
td { iops }
190+
td { throughput }
155191
td { calcCosts(nodes, cpu, memory, volume_size, iops, throughput) }$
156192

157193
td
@@ -229,28 +265,44 @@ postgresqls
229265

230266
const calcCosts = this.calcCosts = (nodes, cpu, memory, disk, iops, throughput) => {
231267
podcount = Math.max(nodes, opts.config.min_pods)
232-
corecost = toCores(cpu) * opts.config.cost_core
233-
memorycost = toMemory(memory) * opts.config.cost_memory
268+
corecost = toCores(cpu) * opts.config.cost_core * 30.5 * 24
269+
memorycost = toMemory(memory) * opts.config.cost_memory * 30.5 * 24
234270
diskcost = toDisk(disk) * opts.config.cost_ebs
235271
iopscost = 0
236-
if (iops !== undefined && iops > 3000) {
237-
iopscost = (iops - 3000) * opts.config.cost_iops
272+
if (iops !== undefined && iops > opts.config.free_iops) {
273+
if (iops > opts.config.limit_iops) {
274+
iops = opts.config.limit_iops
275+
}
276+
iopscost = (iops - opts.config.free_iops) * opts.config.cost_iops
238277
}
239278
throughputcost = 0
240-
if (throughput !== undefined && throughput > 125) {
241-
throughputcost = (throughput - 125) * opts.config.cost_throughput
279+
if (throughput !== undefined && throughput > opts.config.free_throughput) {
280+
if (throughput > opts.config.limit_throughput) {
281+
throughput = opts.config.limit_throughput
282+
}
283+
throughputcost = (throughput - opts.config.free_throughput) * opts.config.cost_throughput
242284
}
243285

244-
costs = podcount * (corecost + memorycost + diskcost + iopscost + throughputcost)
286+
costs = podcount * (Math.max(corecost, memorycost) + diskcost + iopscost + throughputcost)
245287
return costs.toFixed(2)
246288
}
247289

248290
const toDisk = this.toDisk = value => {
249-
if(value.endsWith("Gi")) {
291+
if(value.endsWith("Mi")) {
292+
value = value.substring(0, value.length-2)
293+
value = Number(value) / 1000.
294+
return value
295+
}
296+
else if(value.endsWith("Gi")) {
250297
value = value.substring(0, value.length-2)
251298
value = Number(value)
252299
return value
253300
}
301+
else if(value.endsWith("Ti")) {
302+
value = value.substring(0, value.length-2)
303+
value = Number(value) * 1000
304+
return value
305+
}
254306

255307
return value
256308
}

ui/manifests/deployment.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ spec:
6767
"cost_throughput": 0.0476,
6868
"cost_core": 0.0575,
6969
"cost_memory": 0.014375,
70+
"free_iops": 3000,
71+
"free_throughput": 125,
72+
"limit_iops": 16000,
73+
"limit_throughput": 1000,
7074
"postgresql_versions": [
7175
"14",
7276
"13",

ui/operator_ui/main.py

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -82,21 +82,36 @@
8282
OPERATOR_UI_CONFIG = getenv('OPERATOR_UI_CONFIG', '{}')
8383
OPERATOR_UI_MAINTENANCE_CHECK = getenv('OPERATOR_UI_MAINTENANCE_CHECK', '{}')
8484
READ_ONLY_MODE = getenv('READ_ONLY_MODE', False) in [True, 'true']
85-
RESOURCES_VISIBLE = getenv('RESOURCES_VISIBLE', True)
8685
SPILO_S3_BACKUP_PREFIX = getenv('SPILO_S3_BACKUP_PREFIX', 'spilo/')
8786
SUPERUSER_TEAM = getenv('SUPERUSER_TEAM', 'acid')
8887
TARGET_NAMESPACE = getenv('TARGET_NAMESPACE')
8988
GOOGLE_ANALYTICS = getenv('GOOGLE_ANALYTICS', False)
9089
MIN_PODS= getenv('MIN_PODS', 2)
90+
RESOURCES_VISIBLE = getenv('RESOURCES_VISIBLE', True)
91+
CUSTOM_MESSAGE_RED = getenv('CUSTOM_MESSAGE_RED', '')
92+
93+
APPLICATION_DEPLOYMENT_DOCS = getenv('APPLICATION_DEPLOYMENT_DOCS', '')
94+
CONNECTION_DOCS = getenv('CONNECTION_DOCS', '')
9195

9296
# storage pricing, i.e. https://aws.amazon.com/ebs/pricing/ (e.g. Europe - Franfurt)
9397
COST_EBS = float(getenv('COST_EBS', 0.0952)) # GB per month
9498
COST_IOPS = float(getenv('COST_IOPS', 0.006)) # IOPS per month above 3000 baseline
9599
COST_THROUGHPUT = float(getenv('COST_THROUGHPUT', 0.0476)) # MB/s per month above 125 MB/s baseline
96100

97101
# compute costs, i.e. https://www.ec2instances.info/?region=eu-central-1&selected=m5.2xlarge
98-
COST_CORE = 30.5 * 24 * float(getenv('COST_CORE', 0.0575)) # Core per hour m5.2xlarge / 8.
99-
COST_MEMORY = 30.5 * 24 * float(getenv('COST_MEMORY', 0.014375)) # Memory GB m5.2xlarge / 32.
102+
COST_CORE = float(getenv('COST_CORE', 0.0575)) # Core per hour m5.2xlarge / 8.
103+
COST_MEMORY = float(getenv('COST_MEMORY', 0.014375)) # Memory GB m5.2xlarge / 32.
104+
105+
# maximum and limitation of IOPS and throughput
106+
FREE_IOPS = float(getenv('FREE_IOPS', 3000))
107+
LIMIT_IOPS = float(getenv('LIMIT_IOPS', 16000))
108+
FREE_THROUGHPUT = float(getenv('FREE_THROUGHPUT', 125))
109+
LIMIT_THROUGHPUT = float(getenv('LIMIT_THROUGHPUT', 1000))
110+
# get the default value of core and memory
111+
DEFAULT_MEMORY = getenv('DEFAULT_MEMORY', '300Mi')
112+
DEFAULT_MEMORY_LIMIT = getenv('DEFAULT_MEMORY_LIMIT', '300Mi')
113+
DEFAULT_CPU = getenv('DEFAULT_CPU', '10m')
114+
DEFAULT_CPU_LIMIT = getenv('DEFAULT_CPU_LIMIT', '300m')
100115

101116
WALE_S3_ENDPOINT = getenv(
102117
'WALE_S3_ENDPOINT',
@@ -304,29 +319,34 @@ def index():
304319
'nat_gateways_visible': True,
305320
'users_visible': True,
306321
'databases_visible': True,
307-
'resources_visible': True,
308-
'postgresql_versions': ['11','12','13'],
322+
'resources_visible': RESOURCES_VISIBLE,
323+
'postgresql_versions': ['11','12','13','14'],
309324
'dns_format_string': '{0}.{1}.{2}',
310325
'pgui_link': '',
311326
'static_network_whitelist': {},
327+
'read_only_mode': READ_ONLY_MODE,
328+
'superuser_team': SUPERUSER_TEAM,
329+
'target_namespace': TARGET_NAMESPACE,
330+
'connection_docs': CONNECTION_DOCS,
331+
'application_deployment_docs': APPLICATION_DEPLOYMENT_DOCS,
312332
'cost_ebs': COST_EBS,
313333
'cost_iops': COST_IOPS,
314334
'cost_throughput': COST_THROUGHPUT,
315335
'cost_core': COST_CORE,
316336
'cost_memory': COST_MEMORY,
317-
'min_pods': MIN_PODS
337+
'min_pods': MIN_PODS,
338+
'free_iops': FREE_IOPS,
339+
'free_throughput': FREE_THROUGHPUT,
340+
'limit_iops': LIMIT_IOPS,
341+
'limit_throughput': LIMIT_THROUGHPUT
318342
}
319343

320344

321345
@app.route('/config')
322346
@authorize
323347
def get_config():
324-
config = loads(OPERATOR_UI_CONFIG) or DEFAULT_UI_CONFIG
325-
config['read_only_mode'] = READ_ONLY_MODE
326-
config['resources_visible'] = RESOURCES_VISIBLE
327-
config['superuser_team'] = SUPERUSER_TEAM
328-
config['target_namespace'] = TARGET_NAMESPACE
329-
config['min_pods'] = MIN_PODS
348+
config = DEFAULT_UI_CONFIG.copy()
349+
config.update(loads(OPERATOR_UI_CONFIG))
330350

331351
config['namespaces'] = (
332352
[TARGET_NAMESPACE]

ui/operator_ui/static/styles.css

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,56 @@ label {
6464
td {
6565
vertical-align: middle !important;
6666
}
67+
68+
.tooltip {
69+
position: relative;
70+
display: inline-block;
71+
opacity: 1;
72+
font-size: 14px;
73+
font-weight: bold;
74+
}
75+
.tooltip:after {
76+
content: '?';
77+
display: inline-block;
78+
font-family: sans-serif;
79+
font-weight: bold;
80+
text-align: center;
81+
width: 16px;
82+
height: 16px;
83+
font-size: 12px;
84+
line-height: 16px;
85+
border-radius: 12px;
86+
padding: 0px;
87+
color: white;
88+
background: black;
89+
border: 1px solid black;
90+
}
91+
.tooltip .tooltiptext {
92+
visibility: hidden;
93+
width: 250px;
94+
background-color: white;
95+
color: #000;
96+
text-align: justify;
97+
border-radius: 6px;
98+
padding: 10px 10px;
99+
position: absolute;
100+
z-index: 1;
101+
bottom: 150%;
102+
left: 50%;
103+
margin-left: -120px;
104+
border: 1px solid black;
105+
font-weight: normal;
106+
}
107+
.tooltip .tooltiptext::after {
108+
content: "";
109+
position: absolute;
110+
top: 100%;
111+
left: 50%;
112+
margin-left: -5px;
113+
border-width: 5px;
114+
border-style: solid;
115+
border-color: black transparent transparent transparent;
116+
}
117+
.tooltip:hover .tooltiptext {
118+
visibility: visible;
119+
}

0 commit comments

Comments
 (0)