@@ -33,7 +33,9 @@ import InputRow from "./form-components/InputRow";
3333import Button from "./porter/Button" ;
3434import Error from "./porter/Error" ;
3535import Icon from "./porter/Icon" ;
36+ import InputSlider from "./porter/InputSlider" ;
3637import Link from "./porter/Link" ;
38+ import Select from "./porter/Select" ;
3739import Spacer from "./porter/Spacer" ;
3840import Step from "./porter/Step" ;
3941import Text from "./porter/Text" ;
@@ -53,6 +55,7 @@ type Props = RouteComponentProps & {
5355 provisionerError ?: string ;
5456 credentialId : string ;
5557 clusterId ?: number ;
58+ gpuModal ?: boolean ;
5659} ;
5760
5861const VALID_CIDR_RANGE_PATTERN =
@@ -71,6 +74,11 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
7174 const [ clusterName , setClusterName ] = useState ( "" ) ;
7275 const [ azureLocation , setAzureLocation ] = useState ( "eastus" ) ;
7376 const [ machineType , setMachineType ] = useState ( "Standard_B2als_v2" ) ;
77+ const [ gpuMinInstances , setGpuMinInstances ] = useState ( 1 ) ;
78+ const [ gpuMaxInstances , setGpuMaxInstances ] = useState ( 5 ) ;
79+ const [ gpuInstanceType , setGpuInstanceType ] = useState (
80+ "Standard_NC4as_T4_v3"
81+ ) ;
7482 const [ isExpanded , setIsExpanded ] = useState ( false ) ;
7583 const [ minInstances , setMinInstances ] = useState ( 1 ) ;
7684 const [ maxInstances , setMaxInstances ] = useState ( 10 ) ;
@@ -85,13 +93,22 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
8593 regionFilteredMachineTypeOptions ,
8694 setRegionFilteredMachineTypeOptions ,
8795 ] = useState < MachineTypeOption [ ] > ( azureSupportedMachineTypes ( azureLocation ) ) ;
96+ const [
97+ regionFilteredGPUMachineTypeOptions ,
98+ setRegionFilteredGPUMachineTypeOptions ,
99+ ] = useState < MachineTypeOption [ ] > (
100+ azureSupportedMachineTypes ( azureLocation , true )
101+ ) ;
88102
89103 const { showIntercomWithMessage } = useIntercom ( ) ;
90104
91105 useEffect ( ( ) => {
92106 setRegionFilteredMachineTypeOptions (
93107 azureSupportedMachineTypes ( azureLocation )
94108 ) ;
109+ setRegionFilteredGPUMachineTypeOptions (
110+ azureSupportedMachineTypes ( azureLocation , true )
111+ ) ;
95112 } , [ azureLocation ] ) ;
96113
97114 const markStepStarted = async (
@@ -188,6 +205,42 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
188205 console . log ( err ) ;
189206 }
190207
208+ const nodePools = [
209+ new AKSNodePool ( {
210+ instanceType : "Standard_B2als_v2" ,
211+ minInstances : 1 ,
212+ maxInstances : 3 ,
213+ nodePoolType : NodePoolType . SYSTEM ,
214+ mode : "User" ,
215+ } ) ,
216+ new AKSNodePool ( {
217+ instanceType : "Standard_B2as_v2" ,
218+ minInstances : 1 ,
219+ maxInstances : 3 ,
220+ nodePoolType : NodePoolType . MONITORING ,
221+ mode : "User" ,
222+ } ) ,
223+ new AKSNodePool ( {
224+ instanceType : machineType ,
225+ minInstances : minInstances || 1 ,
226+ maxInstances : maxInstances || 10 ,
227+ nodePoolType : NodePoolType . APPLICATION ,
228+ mode : "User" ,
229+ } ) ,
230+ ] ;
231+
232+ // Conditionally add the last EKSNodeGroup if gpuModal is enabled
233+ if ( props . gpuModal ) {
234+ nodePools . push (
235+ new AKSNodePool ( {
236+ instanceType : gpuInstanceType ,
237+ minInstances : gpuMinInstances || 0 ,
238+ maxInstances : gpuMaxInstances || 5 ,
239+ nodePoolType : NodePoolType . CUSTOM ,
240+ } )
241+ ) ;
242+ }
243+
191244 const data = new Contract ( {
192245 cluster : new Cluster ( {
193246 projectId : currentProject . id ,
@@ -201,29 +254,7 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
201254 clusterVersion : clusterVersion || "v1.27.3" ,
202255 cidrRange : cidrRange || "10.78.0.0/16" ,
203256 location : azureLocation ,
204- nodePools : [
205- new AKSNodePool ( {
206- instanceType : "Standard_B2als_v2" ,
207- minInstances : 1 ,
208- maxInstances : 3 ,
209- nodePoolType : NodePoolType . SYSTEM ,
210- mode : "User" ,
211- } ) ,
212- new AKSNodePool ( {
213- instanceType : "Standard_B2as_v2" ,
214- minInstances : 1 ,
215- maxInstances : 3 ,
216- nodePoolType : NodePoolType . MONITORING ,
217- mode : "User" ,
218- } ) ,
219- new AKSNodePool ( {
220- instanceType : machineType ,
221- minInstances : minInstances || 1 ,
222- maxInstances : maxInstances || 10 ,
223- nodePoolType : NodePoolType . APPLICATION ,
224- mode : "User" ,
225- } ) ,
226- ] ,
257+ nodePools,
227258 skuTier,
228259 } ) ,
229260 } ,
@@ -317,7 +348,10 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
317348
318349 // TODO: pass in contract as the already parsed object, rather than JSON (requires changes to AWS/GCP provisioning)
319350 const contract = Contract . fromJsonString (
320- JSON . stringify ( props . selectedClusterVersion )
351+ JSON . stringify ( props . selectedClusterVersion ) ,
352+ {
353+ ignoreUnknownFields : true ,
354+ }
321355 ) ;
322356
323357 if (
@@ -471,6 +505,46 @@ const AzureProvisionerSettings: React.FC<Props> = (props) => {
471505 ) ;
472506 } ;
473507
508+ if ( props . gpuModal ) {
509+ return (
510+ < >
511+ < Select
512+ options = { regionFilteredGPUMachineTypeOptions }
513+ width = "350px"
514+ disabled = { isReadOnly }
515+ value = { gpuInstanceType }
516+ setValue = { ( x : string ) => {
517+ setGpuInstanceType ( x ) ;
518+ } }
519+ label = "GPU Instance type"
520+ />
521+ < Spacer y = { 1 } />
522+ < InputSlider
523+ label = "Max Instances: "
524+ unit = "nodes"
525+ min = { 0 }
526+ max = { 5 }
527+ step = { 1 }
528+ width = "350px"
529+ disabled = { isReadOnly }
530+ value = { gpuMaxInstances . toString ( ) }
531+ setValue = { ( x : number ) => {
532+ setGpuMaxInstances ( x ) ;
533+ } }
534+ />
535+ < Button
536+ disabled = { isDisabled ( ) }
537+ onClick = { createCluster }
538+ status = { getStatus ( ) }
539+ >
540+ Provision
541+ </ Button >
542+
543+ < Spacer y = { 0.5 } />
544+ </ >
545+ ) ;
546+ }
547+
474548 return (
475549 < >
476550 < StyledForm > { renderForm ( ) } </ StyledForm >
0 commit comments