-
Notifications
You must be signed in to change notification settings - Fork 28
feat: add keda autoscaler for container and application service (only… #2265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: staging
Are you sure you want to change the base?
Conversation
|
Qovery can create a Preview Environment for this PR.
This comment has been generated from Qovery AI 🤖.
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## staging #2265 +/- ##
===========================================
- Coverage 49.14% 47.53% -1.61%
===========================================
Files 811 1263 +452
Lines 16526 23002 +6476
Branches 4854 6757 +1903
===========================================
+ Hits 8121 10935 +2814
- Misses 6880 9964 +3084
- Partials 1525 2103 +578
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
041a81e to
aed396c
Compare
bf0d6ba to
9d0dfd3
Compare
RemiBonnet
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Pierre 🙏
I added a few comments, but I think it would be better if I rewrite this part
The logic feels too complex for what are just small settings, and it currently affects some sensitive parts of the codebase. I think this logic should be isolated, as it is now, it’s hard to maintain and risky. Let’s talk about it tomorrow!
| if (onChange) onChange(e) | ||
| setCurrentValue(e.currentTarget.value) | ||
| }} | ||
| onKeyDown={(e) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can't change UI component need to remove it
| * sanitizeKubernetesName('app__with--special!!!chars') // 'app-with-special-chars' | ||
| * sanitizeKubernetesName('-leading-and-trailing-') // 'leading-and-trailing' | ||
| */ | ||
| export function sanitizeKubernetesName(name: string): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not used ?
| autoscaling_scaler_type: __, | ||
| autoscaling_polling_interval: ___, | ||
| autoscaling_cooldown_period: ____, | ||
| scalers: _____, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to remove the fields field below?
| min_running_instances: number | ||
| max_running_instances: number | ||
|
|
||
| // Autoscaling mode selection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have an specific interface for keda and extends this one? (you can probably extends from the api doc)
...ib/application-settings/ui/application-settings-resources/application-settings-resources.tsx
Show resolved
Hide resolved
| payload, | ||
| }, | ||
| { | ||
| onSuccess: () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to have an try catch instead of add it inside the onSuccess
|
|
||
| editAdvancedSettings({ | ||
| serviceId: service.id, | ||
| payload: advancedPayload as any, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't have any type
|
|
||
| // HPA fields | ||
| hpa_metric_type: (() => { | ||
| const settings = advancedSettings as Record<string, any> | undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't use any
| return 'CPU' | ||
| })(), | ||
| hpa_cpu_average_utilization_percent: (() => { | ||
| const settings = advancedSettings as Record<string, any> | undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't use any
| return 60 | ||
| })(), | ||
| hpa_memory_average_utilization_percent: (() => { | ||
| const settings = advancedSettings as Record<string, any> | undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't use any
7ec2455 to
7a94741
Compare
c03a9b5 to
7195bf1
Compare
RemiBonnet
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Pierre!
I added few comments and if you can all new files inside console-shared should be in your folder keda same for new files inside the util-services 🙏
| @@ -0,0 +1,88 @@ | |||
| import type { ScaledObjectStatusDto } from 'qovery-ws-typescript-axios/dist/api' | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add an folder keda and add files associated inside ?
keda
- scaled-object-status/scaled-object-status
- keda-settings/keda-settings
- autoscaling-payload/autoscaling-payload
| @@ -0,0 +1,88 @@ | |||
| import type { ScaledObjectStatusDto } from 'qovery-ws-typescript-axios/dist/api' | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| import type { ScaledObjectStatusDto } from 'qovery-ws-typescript-axios/dist/api' | |
| import type { ScaledObjectStatusDto } from 'qovery-ws-typescript-axios' |
| import { isHelmGitSource, isHelmRepositorySource, isJobContainerSource, isJobGitSource } from '@qovery/shared/enums' | ||
| import { type ApplicationGeneralData, type JobGeneralData } from '@qovery/shared/interfaces' | ||
| import { joinArgsWithQuotes, parseCmd } from '@qovery/shared/util-js' | ||
| import { convertAutoscalingResponseToRequest } from '@qovery/shared/util-services' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment below. It would be better to add it directly inside the keda folder.
Keeping a dedicated keda folder makes sense because we’re not sure about the future of this feature, the design may change, so having the file in a single place is safer and easier to maintain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
| extractAndProcessAutoscaling, | ||
| } from './autoscaling-payload' | ||
|
|
||
| type TestAutoscalingRequest = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can't have a type here, should be import from the .ts and not the spec
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
| const gpu = Number(resourcesData['gpu']) | ||
| const variableImportRequest = prepareVariableImportRequest(variablesData) | ||
|
|
||
| // Parse KEDA autoscaling if autoscaling mode is KEDA (or legacy autoscaling_enabled for backward compatibility) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you create an util in the folder keda of your domain?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
| ], | ||
| } | ||
|
|
||
| const result = convertAutoscalingResponseToRequest(response as any) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to remove all as any in your PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
| }) | ||
|
|
||
| it('should use default values for KEDA when not provided', () => { | ||
| const formData: any = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to remove all any in your PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
| <div className="mb-5"> | ||
| <label className="mb-3 block text-sm font-medium text-neutral-400">Autoscaling metric</label> | ||
| <div className="flex flex-col gap-3"> | ||
| <InputRadio |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This component InputRadio is deprecated you need to use RadioGroup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
| ) : null} | ||
|
|
||
| {/* Mode NONE: Fixed instances */} | ||
| {autoscalingMode === 'NONE' && ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pggb25 Could you use ts-pattern's match method instead ? That way we're sure all cases are covered.
...ib/application-settings/ui/application-settings-resources/application-settings-resources.tsx
Show resolved
Hide resolved
| ): Record<string, unknown> { | ||
| const autoscalingMode = formData['autoscaling_mode'] || 'NONE' | ||
|
|
||
| switch (autoscalingMode) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pggb25 Instead of a switch case, can you please use ts-pattern's match function 🙏
| const autoscalingMode = request.autoscaling_mode | ||
|
|
||
| // KEDA mode: use scalers | ||
| if (autoscalingMode === 'KEDA' && request.scalers?.length) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pggb25 Here, I'd suggest to use ts-pattern's match function as well, instead of a type-unsafe condition
c57c64a to
900321c
Compare
| const isProduction = environmentMode === EnvironmentModeEnum.PRODUCTION | ||
| const hasLowMinimum = (minRunningInstances ?? 0) <= 1 | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pggb25 These variables are not used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
900321c to
5dbde4f
Compare
… qovery admin)
Summary
Issue:
Screenshots / Recordings
Testing
yarn testoryarn test -u(if you need to regenerate snapshots)yarn formatyarn lintPR Checklist
.cursor/rules)feat(service): add new Terraform service) - required for semantic-release