From 6268fb826a157a4cd46eafbcc0aa5c350d5c9a7b Mon Sep 17 00:00:00 2001 From: idanovinda Date: Thu, 19 May 2022 11:00:11 +0200 Subject: [PATCH] update column and cost function (#1894) --- ui/app/src/postgresqls.tag.pug | 72 +++++++++++++++++++++++++++----- ui/manifests/deployment.yaml | 4 ++ ui/operator_ui/main.py | 44 +++++++++++++------ ui/operator_ui/static/styles.css | 53 +++++++++++++++++++++++ 4 files changed, 151 insertions(+), 22 deletions(-) diff --git a/ui/app/src/postgresqls.tag.pug b/ui/app/src/postgresqls.tag.pug index fabf769a0..742bb2968 100644 --- a/ui/app/src/postgresqls.tag.pug +++ b/ui/app/src/postgresqls.tag.pug @@ -51,7 +51,23 @@ postgresqls th(style='width: 140px') CPU th(style='width: 130px') Memory th(style='width: 100px') Size - th(style='width: 120px') Cost/Month + th(style='width: 100px') IOPS + th(style='width: 100px') Throughput + th(style='width: 120px') + .tooltip(style='width: 120px') + | Cost/Month + .tooltiptext + strong Cost = MAX(CPU, Memory) + rest + br + | 1 CPU core : 42.09$ + br + | 1GB memory: 10.5225$ + br + | 1GB volume: 0.0952$ + br + | IOPS (-3000 baseline): 0.006$ + br + | Throughput (-125 baseline): 0.0476$ th(stlye='width: 120px') tbody @@ -69,6 +85,8 @@ postgresqls td { cpu } / { cpu_limit } td { memory } / { memory_limit } td { volume_size } + td { iops } + td { throughput } td { calcCosts(nodes, cpu, memory, volume_size, iops, throughput) }$ td @@ -132,7 +150,23 @@ postgresqls th(style='width: 140px') CPU th(style='width: 130px') Memory th(style='width: 100px') Size - th(style='width: 120px') Cost/Month + th(style='width: 100px') IOPS + th(style='width: 100px') Throughput + th(style='width: 120px') + .tooltip(style='width: 120px') + | Cost/Month + .tooltiptext + strong Cost = MAX(CPU, Memory) + rest + br + | 1 CPU core : 42.09$ + br + | 1GB memory: 10.5225$ + br + | 1GB volume: 0.0952$ + br + | IOPS (-3000 baseline): 0.006$ + br + | Throughput (-125 baseline): 0.0476$ th(stlye='width: 120px') tbody @@ -152,6 +186,8 @@ postgresqls td { cpu } / { cpu_limit } td { memory } / { memory_limit } td { volume_size } + td { iops } + td { throughput } td { calcCosts(nodes, cpu, memory, volume_size, iops, throughput) }$ td @@ -229,28 +265,44 @@ postgresqls const calcCosts = this.calcCosts = (nodes, cpu, memory, disk, iops, throughput) => { podcount = Math.max(nodes, opts.config.min_pods) - corecost = toCores(cpu) * opts.config.cost_core - memorycost = toMemory(memory) * opts.config.cost_memory + corecost = toCores(cpu) * opts.config.cost_core * 30.5 * 24 + memorycost = toMemory(memory) * opts.config.cost_memory * 30.5 * 24 diskcost = toDisk(disk) * opts.config.cost_ebs iopscost = 0 - if (iops !== undefined && iops > 3000) { - iopscost = (iops - 3000) * opts.config.cost_iops + if (iops !== undefined && iops > opts.config.free_iops) { + if (iops > opts.config.limit_iops) { + iops = opts.config.limit_iops + } + iopscost = (iops - opts.config.free_iops) * opts.config.cost_iops } throughputcost = 0 - if (throughput !== undefined && throughput > 125) { - throughputcost = (throughput - 125) * opts.config.cost_throughput + if (throughput !== undefined && throughput > opts.config.free_throughput) { + if (throughput > opts.config.limit_throughput) { + throughput = opts.config.limit_throughput + } + throughputcost = (throughput - opts.config.free_throughput) * opts.config.cost_throughput } - costs = podcount * (corecost + memorycost + diskcost + iopscost + throughputcost) + costs = podcount * (Math.max(corecost, memorycost) + diskcost + iopscost + throughputcost) return costs.toFixed(2) } const toDisk = this.toDisk = value => { - if(value.endsWith("Gi")) { + if(value.endsWith("Mi")) { + value = value.substring(0, value.length-2) + value = Number(value) / 1000. + return value + } + else if(value.endsWith("Gi")) { value = value.substring(0, value.length-2) value = Number(value) return value } + else if(value.endsWith("Ti")) { + value = value.substring(0, value.length-2) + value = Number(value) * 1000 + return value + } return value } diff --git a/ui/manifests/deployment.yaml b/ui/manifests/deployment.yaml index 18d33d323..6140c0f7d 100644 --- a/ui/manifests/deployment.yaml +++ b/ui/manifests/deployment.yaml @@ -67,6 +67,10 @@ spec: "cost_throughput": 0.0476, "cost_core": 0.0575, "cost_memory": 0.014375, + "free_iops": 3000, + "free_throughput": 125, + "limit_iops": 16000, + "limit_throughput": 1000, "postgresql_versions": [ "14", "13", diff --git a/ui/operator_ui/main.py b/ui/operator_ui/main.py index c34ffd4f2..b671c4a01 100644 --- a/ui/operator_ui/main.py +++ b/ui/operator_ui/main.py @@ -82,12 +82,16 @@ OPERATOR_CLUSTER_NAME_LABEL = getenv('OPERATOR_CLUSTER_NAME_LABEL', 'cluster-nam OPERATOR_UI_CONFIG = getenv('OPERATOR_UI_CONFIG', '{}') OPERATOR_UI_MAINTENANCE_CHECK = getenv('OPERATOR_UI_MAINTENANCE_CHECK', '{}') READ_ONLY_MODE = getenv('READ_ONLY_MODE', False) in [True, 'true'] -RESOURCES_VISIBLE = getenv('RESOURCES_VISIBLE', True) SPILO_S3_BACKUP_PREFIX = getenv('SPILO_S3_BACKUP_PREFIX', 'spilo/') SUPERUSER_TEAM = getenv('SUPERUSER_TEAM', 'acid') TARGET_NAMESPACE = getenv('TARGET_NAMESPACE') GOOGLE_ANALYTICS = getenv('GOOGLE_ANALYTICS', False) MIN_PODS= getenv('MIN_PODS', 2) +RESOURCES_VISIBLE = getenv('RESOURCES_VISIBLE', True) +CUSTOM_MESSAGE_RED = getenv('CUSTOM_MESSAGE_RED', '') + +APPLICATION_DEPLOYMENT_DOCS = getenv('APPLICATION_DEPLOYMENT_DOCS', '') +CONNECTION_DOCS = getenv('CONNECTION_DOCS', '') # storage pricing, i.e. https://aws.amazon.com/ebs/pricing/ (e.g. Europe - Franfurt) COST_EBS = float(getenv('COST_EBS', 0.0952)) # GB per month @@ -95,8 +99,19 @@ COST_IOPS = float(getenv('COST_IOPS', 0.006)) # IOPS per month above 3000 basel COST_THROUGHPUT = float(getenv('COST_THROUGHPUT', 0.0476)) # MB/s per month above 125 MB/s baseline # compute costs, i.e. https://www.ec2instances.info/?region=eu-central-1&selected=m5.2xlarge -COST_CORE = 30.5 * 24 * float(getenv('COST_CORE', 0.0575)) # Core per hour m5.2xlarge / 8. -COST_MEMORY = 30.5 * 24 * float(getenv('COST_MEMORY', 0.014375)) # Memory GB m5.2xlarge / 32. +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. + +# maximum and limitation of IOPS and throughput +FREE_IOPS = float(getenv('FREE_IOPS', 3000)) +LIMIT_IOPS = float(getenv('LIMIT_IOPS', 16000)) +FREE_THROUGHPUT = float(getenv('FREE_THROUGHPUT', 125)) +LIMIT_THROUGHPUT = float(getenv('LIMIT_THROUGHPUT', 1000)) +# get the default value of core and memory +DEFAULT_MEMORY = getenv('DEFAULT_MEMORY', '300Mi') +DEFAULT_MEMORY_LIMIT = getenv('DEFAULT_MEMORY_LIMIT', '300Mi') +DEFAULT_CPU = getenv('DEFAULT_CPU', '10m') +DEFAULT_CPU_LIMIT = getenv('DEFAULT_CPU_LIMIT', '300m') WALE_S3_ENDPOINT = getenv( 'WALE_S3_ENDPOINT', @@ -304,29 +319,34 @@ DEFAULT_UI_CONFIG = { 'nat_gateways_visible': True, 'users_visible': True, 'databases_visible': True, - 'resources_visible': True, - 'postgresql_versions': ['11','12','13'], + 'resources_visible': RESOURCES_VISIBLE, + 'postgresql_versions': ['11','12','13','14'], 'dns_format_string': '{0}.{1}.{2}', 'pgui_link': '', 'static_network_whitelist': {}, + 'read_only_mode': READ_ONLY_MODE, + 'superuser_team': SUPERUSER_TEAM, + 'target_namespace': TARGET_NAMESPACE, + 'connection_docs': CONNECTION_DOCS, + 'application_deployment_docs': APPLICATION_DEPLOYMENT_DOCS, 'cost_ebs': COST_EBS, 'cost_iops': COST_IOPS, 'cost_throughput': COST_THROUGHPUT, 'cost_core': COST_CORE, 'cost_memory': COST_MEMORY, - 'min_pods': MIN_PODS + 'min_pods': MIN_PODS, + 'free_iops': FREE_IOPS, + 'free_throughput': FREE_THROUGHPUT, + 'limit_iops': LIMIT_IOPS, + 'limit_throughput': LIMIT_THROUGHPUT } @app.route('/config') @authorize def get_config(): - config = loads(OPERATOR_UI_CONFIG) or DEFAULT_UI_CONFIG - config['read_only_mode'] = READ_ONLY_MODE - config['resources_visible'] = RESOURCES_VISIBLE - config['superuser_team'] = SUPERUSER_TEAM - config['target_namespace'] = TARGET_NAMESPACE - config['min_pods'] = MIN_PODS + config = DEFAULT_UI_CONFIG.copy() + config.update(loads(OPERATOR_UI_CONFIG)) config['namespaces'] = ( [TARGET_NAMESPACE] diff --git a/ui/operator_ui/static/styles.css b/ui/operator_ui/static/styles.css index 3f05cb290..42182cc76 100644 --- a/ui/operator_ui/static/styles.css +++ b/ui/operator_ui/static/styles.css @@ -64,3 +64,56 @@ label { td { vertical-align: middle !important; } + +.tooltip { + position: relative; + display: inline-block; + opacity: 1; + font-size: 14px; + font-weight: bold; +} +.tooltip:after { + content: '?'; + display: inline-block; + font-family: sans-serif; + font-weight: bold; + text-align: center; + width: 16px; + height: 16px; + font-size: 12px; + line-height: 16px; + border-radius: 12px; + padding: 0px; + color: white; + background: black; + border: 1px solid black; +} +.tooltip .tooltiptext { + visibility: hidden; + width: 250px; + background-color: white; + color: #000; + text-align: justify; + border-radius: 6px; + padding: 10px 10px; + position: absolute; + z-index: 1; + bottom: 150%; + left: 50%; + margin-left: -120px; + border: 1px solid black; + font-weight: normal; +} +.tooltip .tooltiptext::after { + content: ""; + position: absolute; + top: 100%; + left: 50%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: black transparent transparent transparent; +} +.tooltip:hover .tooltiptext { + visibility: visible; +}