diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-10 00:08:21 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-10 00:08:21 +0300 |
commit | 64786982930713d095ccd3aebd812182a1879fed (patch) | |
tree | 542e79df02f79049d8a63b31388c7d1e3e3b9166 /app/assets/javascripts/clusters_list | |
parent | 3d0474695407d24d49bb94f29a182739ee35e1f8 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/clusters_list')
-rw-r--r-- | app/assets/javascripts/clusters_list/components/clusters.vue | 141 |
1 files changed, 132 insertions, 9 deletions
diff --git a/app/assets/javascripts/clusters_list/components/clusters.vue b/app/assets/javascripts/clusters_list/components/clusters.vue index 0404c8cdfed..58b16f35347 100644 --- a/app/assets/javascripts/clusters_list/components/clusters.vue +++ b/app/assets/javascripts/clusters_list/components/clusters.vue @@ -1,10 +1,12 @@ <script> +import * as Sentry from '@sentry/browser'; import { mapState, mapActions } from 'vuex'; import { GlDeprecatedBadge as GlBadge, GlLink, GlLoadingIcon, GlPagination, + GlSprintf, GlTable, } from '@gitlab/ui'; import tooltip from '~/vue_shared/directives/tooltip'; @@ -12,11 +14,14 @@ import { CLUSTER_TYPES, STATUSES } from '../constants'; import { __, sprintf } from '~/locale'; export default { + nodeMemoryText: __('%{totalMemory} (%{freeSpacePercentage}%{percentSymbol} free)'), + nodeCpuText: __('%{totalCpu} (%{freeSpacePercentage}%{percentSymbol} free)'), components: { GlBadge, GlLink, GlLoadingIcon, GlPagination, + GlSprintf, GlTable, }, directives: { @@ -47,15 +52,14 @@ export default { key: 'node_size', label: __('Nodes'), }, - // Fields are missing calculation methods and not ready to display - // { - // key: 'node_cpu', - // label: __('Total cores (vCPUs)'), - // }, - // { - // key: 'node_memory', - // label: __('Total memory (GB)'), - // }, + { + key: 'total_cpu', + label: __('Total cores (CPUs)'), + }, + { + key: 'total_memory', + label: __('Total memory (GB)'), + }, { key: 'cluster_type', label: __('Cluster level'), @@ -72,11 +76,102 @@ export default { }, methods: { ...mapActions(['fetchClusters', 'setPage']), + k8sQuantityToGb(quantity) { + if (!quantity) { + return 0; + } else if (quantity.endsWith(__('Ki'))) { + return parseInt(quantity.substr(0, quantity.length - 2), 10) * 0.000001024; + } else if (quantity.endsWith(__('Mi'))) { + return parseInt(quantity.substr(0, quantity.length - 2), 10) * 0.001048576; + } + // We are trying to track quantity types coming from Kubernetes. + // Sentry will notify us if we are missing types. + throw new Error(`UnknownK8sMemoryQuantity:${quantity}`); + }, + k8sQuantityToCpu(quantity) { + if (!quantity) { + return 0; + } else if (quantity.endsWith('m')) { + return parseInt(quantity.substr(0, quantity.length - 1), 10) / 1000.0; + } else if (quantity.endsWith('n')) { + return parseInt(quantity.substr(0, quantity.length - 1), 10) / 1000000000.0; + } + + // We are trying to track quantity types coming from Kubernetes. + // Sentry will notify us if we are missing types. + throw new Error(`UnknownK8sCpuQuantity:${quantity}`); + }, statusTitle(status) { const iconTitle = STATUSES[status] || STATUSES.default; return sprintf(__('Status: %{title}'), { title: iconTitle.title }, false); }, + totalMemoryAndUsage(nodes) { + try { + // For EKS node.usage will not be present unless the user manually + // install the metrics server + if (nodes && nodes[0].usage) { + let totalAllocatableMemory = 0; + let totalUsedMemory = 0; + + nodes.reduce((total, node) => { + const allocatableMemoryQuantity = node.status.allocatable.memory; + const allocatableMemoryGb = this.k8sQuantityToGb(allocatableMemoryQuantity); + totalAllocatableMemory += allocatableMemoryGb; + + const usedMemoryQuantity = node.usage.memory; + const usedMemoryGb = this.k8sQuantityToGb(usedMemoryQuantity); + totalUsedMemory += usedMemoryGb; + + return null; + }, 0); + + const freeSpacePercentage = (1 - totalUsedMemory / totalAllocatableMemory) * 100; + + return { + totalMemory: totalAllocatableMemory.toFixed(2), + freeSpacePercentage: Math.round(freeSpacePercentage), + }; + } + } catch (error) { + Sentry.captureException(error); + } + + return { totalMemory: null, freeSpacePercentage: null }; + }, + totalCpuAndUsage(nodes) { + try { + // For EKS node.usage will not be present unless the user manually + // install the metrics server + if (nodes && nodes[0].usage) { + let totalAllocatableCpu = 0; + let totalUsedCpu = 0; + + nodes.reduce((total, node) => { + const allocatableCpuQuantity = node.status.allocatable.cpu; + const allocatableCpu = this.k8sQuantityToCpu(allocatableCpuQuantity); + totalAllocatableCpu += allocatableCpu; + + const usedCpuQuantity = node.usage.cpu; + const usedCpuGb = this.k8sQuantityToCpu(usedCpuQuantity); + totalUsedCpu += usedCpuGb; + + return null; + }, 0); + + const freeSpacePercentage = (1 - totalUsedCpu / totalAllocatableCpu) * 100; + + return { + totalCpu: totalAllocatableCpu.toFixed(2), + freeSpacePercentage: Math.round(freeSpacePercentage), + }; + } + } catch (error) { + Sentry.captureException(error); + } + + return { totalCpu: null, freeSpacePercentage: null }; + }, }, }; </script> @@ -109,6 +204,34 @@ export default { }}</small> </template> + <template #cell(total_cpu)="{ item }"> + <span v-if="item.nodes"> + <gl-sprintf :message="$options.nodeCpuText"> + <template #totalCpu>{{ totalCpuAndUsage(item.nodes).totalCpu }}</template> + <template #freeSpacePercentage>{{ + totalCpuAndUsage(item.nodes).freeSpacePercentage + }}</template> + <template #percentSymbol + >%</template + > + </gl-sprintf> + </span> + </template> + + <template #cell(total_memory)="{ item }"> + <span v-if="item.nodes"> + <gl-sprintf :message="$options.nodeMemoryText"> + <template #totalMemory>{{ totalMemoryAndUsage(item.nodes).totalMemory }}</template> + <template #freeSpacePercentage>{{ + totalMemoryAndUsage(item.nodes).freeSpacePercentage + }}</template> + <template #percentSymbol + >%</template + > + </gl-sprintf> + </span> + </template> + <template #cell(cluster_type)="{value}"> <gl-badge variant="light"> {{ value }} |