Skip to content

Commit

Permalink
chore: pr review fixies
Browse files Browse the repository at this point in the history
  • Loading branch information
Kolezhanchik committed Sep 27, 2024
1 parent 32a9d30 commit 87b07b6
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export default privateCloudProductUsageMetrics(({ pathParams, queryParams, sessi
const handleNamespaceChange = (namespace: string) => {
setenvironment(namespace);
};
console.log('data', data);

return (
<div>
<fieldset className="w-full md:w-48 2xl:w-64 pb-6">
Expand Down
22 changes: 13 additions & 9 deletions app/components/table/TableBodyMetrics.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';

import classNames from 'classnames';
import _truncate from 'lodash-es/truncate';
import React from 'react';
import { getTotalMetrics, ResourceType, Pod } from '@/services/openshift-kubernetis-metrics/helpers';
Expand Down Expand Up @@ -88,9 +89,12 @@ export default function TableBodyMetrics({ pods, resource, title, measurementUni
{rows.map((row, index) => (
<div key={row.podName}>
<div
className={`hover:bg-gray-100 transition-colors duration-200 grid grid-cols-1 md:grid-cols-6 lg:grid-cols-12 gap-4 px-4 py-3 sm:px-6 lg:px-8 ${
index === 0 && 'bg-gray-100'
}`}
className={classNames(
'hover:bg-gray-100 transition-colors duration-200 grid grid-cols-1 md:grid-cols-6 lg:grid-cols-12 gap-4 px-4 py-3 sm:px-6 lg:px-8',
{
'bg-gray-100': index === 0,
},
)}
>
<div className="md:col-span-1 lg:col-span-3">
<TruncatedTooltip label={row.podName}>
Expand All @@ -99,20 +103,20 @@ export default function TableBodyMetrics({ pods, resource, title, measurementUni
</div>
<div className="md:col-span-1 lg:col-span-3">
<TruncatedTooltip label={row.containerName}>
<span className={`${index === 0 && 'font-bold'}`}>
<span className={classNames({ 'font-bold': index === 0 })}>
{_truncate(row.containerName, { length: 100 })}
</span>
</TruncatedTooltip>
</div>
<div className={`md:col-span-1 lg:col-span-2 ${index === 0 && 'font-bold'}`}>
<div className={classNames('md:col-span-1 lg:col-span-2', { 'font-bold': index === 0 })}>
{row.usage[resource]}
{index !== 0 && measurementUnit}
</div>
<div className={`md:col-span-1 lg:col-span-2 ${index === 0 && 'font-bold'}`}>
<div className={classNames('md:col-span-1 lg:col-span-2', { 'font-bold': index === 0 })}>
{row.limits[resource]}
{index !== 0 && measurementUnit}
</div>
<div className={`md:col-span-1 lg:col-span-2 ${index === 0 && 'font-bold'}`}>
<div className={classNames('md:col-span-1 lg:col-span-2', { 'font-bold': index === 0 })}>
{row.requests[resource]}
{index !== 0 && measurementUnit}
</div>
Expand All @@ -130,11 +134,11 @@ export default function TableBodyMetrics({ pods, resource, title, measurementUni
index === 0 && 'bg-gray-100'
}`}
>
<div className={`md:col-span-3 lg:col-span-3 text-center ${index === 0 && 'font-bold'}`}>
<div className={classNames('md:col-span-3 lg:col-span-3 text-center', { 'font-bold': index === 0 })}>
{row.totalLimit}
{index !== 0 && measurementUnit}
</div>
<div className={`md:col-span-3 lg:col-span-3 text-center ${index === 0 && 'font-bold'}`}>
<div className={classNames('md:col-span-3 lg:col-span-3 text-center', { 'font-bold': index === 0 })}>
{row.totalUsage}
{index !== 0 && measurementUnit}
</div>
Expand Down
87 changes: 44 additions & 43 deletions app/helpers/auto-approval-check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export interface Quotas {
}

// check if request contains quota change
export const checknoQuotaChange = (currentQuota: Quotas, requestedQuota: Quotas): boolean => {
export const checkNoQuotaChange = (currentQuota: Quotas, requestedQuota: Quotas): boolean => {
let noQuotaChange = true;
// @ts-ignore
_each(currentQuota, (quota: Quota, envQuota: keyof Quotas) => {
Expand All @@ -28,6 +28,7 @@ export const checknoQuotaChange = (currentQuota: Quotas, requestedQuota: Quotas)
_each(quota, (resource: string, resourceName: keyof Quota) => {
const currentVal = resource;
const requestedVal = requestedQuota[envQuota][resourceName];

if (extractNumbers(requestedVal)[0] !== extractNumbers(currentVal)[0]) {
noQuotaChange = false;
return;
Expand All @@ -40,17 +41,18 @@ export const checknoQuotaChange = (currentQuota: Quotas, requestedQuota: Quotas)
// if quota was changed check if it was undngrade quota request
// TODO replace isQuotaUpgrade at app/emails/_templates/private-cloud/TeamEditRequest.tsx
export const checkIfQuotaUpgrade = (currentQuota: Quotas, requestedQuota: Quotas) => {
let ifQuotaUpgrade = true;
// @ts-ignore
_each(currentQuota, (quota: Quota, envQuota: keyof Quotas) => {
// @ts-ignore
_each(quota, (resource: string, resourceName: keyof Quota) => {
const currentVal = resource;
const requestedVal = requestedQuota[envQuota][resourceName];
ifQuotaUpgrade = extractNumbers(requestedVal)[0] > extractNumbers(currentVal)[0];
return Object.keys(currentQuota).some((envQuota) => {
const currentEnvQuota = currentQuota[envQuota as keyof Quotas];
const requestedEnvQuota = requestedQuota[envQuota as keyof Quotas];

return Object.keys(currentEnvQuota).some((resourceName) => {
const currentVal = currentEnvQuota[resourceName as keyof Quota];
const requestedVal = requestedEnvQuota[resourceName as keyof Quota];

// Check if the requested value exceeds the current value
return extractNumbers(requestedVal)[0] > extractNumbers(currentVal)[0];
});
});
return ifQuotaUpgrade;
};

const resourceOrders = {
Expand All @@ -61,7 +63,6 @@ const resourceOrders = {

// Helper function to check resource utilization
const checkUtilization = async (
requestedQuota: Quotas,
currentQuota: Quotas,
licencePlate: string,
cluster: Cluster,
Expand All @@ -74,18 +75,20 @@ const checkUtilization = async (
const { totalUsage } = getTotalMetrics(podMetricsData, resource);
const mesUnitsCoeff = resource === 'cpu' ? 1000 : 1024 * 1024;
const totalLimit = extractNumbers(currentQuota[NamespaceNames[namespace]][resource])[1] * mesUnitsCoeff;
const currentUsage = extractNumbers(currentQuota[NamespaceNames[namespace]][resource])[0] * mesUnitsCoeff;

// Check quota utilization
// Current Usage in Percentage=( Total Quota Limit/Current Usage)×100
// namespace already use 85% of total limit(i.e: kube_pod_container_resource_limits/namespace-total-limit)(CPU or memory, or storage)
if (totalLimit && totalUsage) {
const utilizationPercentage = (totalLimit / totalUsage) * 100;
if (utilizationPercentage < 86) {
if (totalLimit && totalUsage && currentUsage) {
const utilizationPercentage = (totalLimit / currentUsage) * 100;
if (utilizationPercentage > 86) {
return true; // Auto-approval due to utilization percentage
}
// Check quota usage
// Utilization Rate=( Requested Resources Actual Usage )×100
// namespace has at least 35% of CPU utilization rate(namespace:container_cpu_usage/namespace_cpu:kube_pod_container_resource_requests:sum > 35%, same idea for memory)
const requestedUsage = extractNumbers(requestedQuota[NamespaceNames[namespace]][resource])[0] * mesUnitsCoeff;
const requestedUtilizationRate = (requestedUsage / totalUsage) * 100;
const requestedUtilizationRate = (currentUsage / totalUsage) * 100;
if (requestedUtilizationRate > 34) {
return true; // Auto-approval due to utilization percentage
}
Expand All @@ -94,7 +97,6 @@ const checkUtilization = async (
};

const checkIfResourceUtilized = async (
requestedQuota: Quotas,
currentQuota: Quotas,
licencePlate: string,
cluster: Cluster,
Expand All @@ -109,7 +111,6 @@ const checkIfResourceUtilized = async (
const utilizationChecks = filteredNamespaces.flatMap((namespace) =>
resourceNames.map((resource) =>
checkUtilization(
requestedQuota,
currentQuota,
licencePlate,
cluster,
Expand All @@ -131,20 +132,21 @@ export const checkIfQuotaAutoApproval = async (
licencePlate: string,
cluster: Cluster,
) => {
const noQuotaChange = checknoQuotaChange(currentQuota, requestedQuota);
let isAutoApprovalAvailable = noQuotaChange;
const castCurrentQuota = {
testQuota: currentQuota.testQuota,
toolsQuota: currentQuota.toolsQuota,
developmentQuota: currentQuota.developmentQuota,
productionQuota: currentQuota.productionQuota,
};

let isAutoApprovalAvailable = checkNoQuotaChange(castCurrentQuota, requestedQuota);
if (!isAutoApprovalAvailable) {
isAutoApprovalAvailable = !checkIfQuotaUpgrade(castCurrentQuota, requestedQuota);
}
const namespaceNames: string[] = [];
const resourceNames: string[] = [];
if (!noQuotaChange) {
if (!isAutoApprovalAvailable) {
let hasIncreasedSignificantly = false;

const castCurrentQuota = {
testQuota: currentQuota.testQuota,
toolsQuota: currentQuota.toolsQuota,
developmentQuota: currentQuota.developmentQuota,
productionQuota: currentQuota.productionQuota,
};

// Iterate over each environment's quota
// @ts-ignore
_each(castCurrentQuota, (quota: Quota, envQuota: keyof Quotas) => {
Expand All @@ -159,12 +161,12 @@ export const checkIfQuotaAutoApproval = async (
const requestedIndex = Object.keys(resourceOrder).indexOf(requestedResource);

const isIncreased = requestedIndex > currentIndex;

if (isIncreased) {
isAutoApprovalAvailable = false;
// Check if the increase is significant(more than next tier)
hasIncreasedSignificantly = requestedIndex - currentIndex > 1;
if (hasIncreasedSignificantly) {
isAutoApprovalAvailable = false;
return;
}
// If not a significant increase, check resource utilization
Expand All @@ -175,18 +177,17 @@ export const checkIfQuotaAutoApproval = async (
}
});
});
}
// TODO remove condition if storage metrics are availiabe
if (resourceNames.indexOf('storage') === -1) {
isAutoApprovalAvailable = await checkIfResourceUtilized(
requestedQuota,
currentQuota,
licencePlate,
cluster,
namespaceNames,
resourceNames,
);
}

return { isAutoApprovalAvailable, noQuotaChange };
// TODO remove condition if storage metrics are availiabe
if (namespaceNames.length > 0 && resourceNames.indexOf('storage') === -1) {
isAutoApprovalAvailable = await checkIfResourceUtilized(
currentQuota,
licencePlate,
cluster,
namespaceNames,
resourceNames,
);
}
}
return isAutoApprovalAvailable;
};
8 changes: 4 additions & 4 deletions app/request-actions/private-cloud/edit-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ export default async function editRequest(

const hasGolddrEnabledChanged = project.cluster === Cluster.GOLD && project.golddrEnabled !== formData.golddrEnabled;

const quotaReviewResult = await checkIfQuotaAutoApproval(
const isAutoApprovalAvailable = await checkIfQuotaAutoApproval(
project as Quotas,
formData as Quotas,
project.licencePlate,
project.cluster,
);

// If there is no quota change or no quota upgrade and no golddr flag changes, the request is automatically approved
if (quotaReviewResult.isAutoApprovalAvailable && !hasGolddrEnabledChanged) {
if (isAutoApprovalAvailable && !hasGolddrEnabledChanged) {
decisionStatus = DecisionStatus.APPROVED;
} else {
decisionStatus = DecisionStatus.PENDING;
Expand All @@ -75,7 +75,7 @@ export default async function editRequest(

const { changes, ...otherChangeMeta } = comparePrivateProductData(rest, previousRequest?.decisionData);

const quotaChangeInfo = quotaReviewResult.noQuotaChange
const quotaChangeInfo = isAutoApprovalAvailable
? {}
: {
quotaContactName,
Expand All @@ -87,7 +87,7 @@ export default async function editRequest(
data: {
type: RequestType.EDIT,
decisionStatus,
isQuotaChanged: !quotaReviewResult.noQuotaChange,
isQuotaChanged: !isAutoApprovalAvailable,
...quotaChangeInfo,
active: true,
createdBy: { connect: { email: session.user.email } },
Expand Down

0 comments on commit 87b07b6

Please sign in to comment.