@@ -2,6 +2,8 @@ package instance
22
33import (
44 "context"
5+ "errors"
6+ "fmt"
57 "sort"
68 "strings"
79
@@ -32,6 +34,17 @@ var serverTypesAvailabilityMarshalSpecs = human.EnumMarshalSpecs{
3234// Builders
3335//
3436
37+ type customServerType struct {
38+ Name string `json:"name"`
39+ HourlyPrice * scw.Money `json:"hourly_price"`
40+ LocalVolumeMaxSize scw.Size `json:"local_volume_max_size"`
41+ CPU uint32 `json:"cpu"`
42+ GPU * uint64 `json:"gpu"`
43+ RAM scw.Size `json:"ram"`
44+ Arch instance.Arch `json:"arch"`
45+ Availability instance.ServerTypesAvailability `json:"availability"`
46+ }
47+
3548// serverTypeListBuilder transforms the server map into a list to display a
3649// table of server types instead of a flat key/value list.
3750// We need it for:
@@ -63,17 +76,6 @@ func serverTypeListBuilder(c *core.Command) *core.Command {
6376 }
6477
6578 c .Run = func (ctx context.Context , argsI interface {}) (interface {}, error ) {
66- type customServerType struct {
67- Name string `json:"name"`
68- HourlyPrice * scw.Money `json:"hourly_price"`
69- LocalVolumeMaxSize scw.Size `json:"local_volume_max_size"`
70- CPU uint32 `json:"cpu"`
71- GPU * uint64 `json:"gpu"`
72- RAM scw.Size `json:"ram"`
73- Arch instance.Arch `json:"arch"`
74- Availability instance.ServerTypesAvailability `json:"availability"`
75- }
76-
7779 api := instance .NewAPI (core .ExtractClient (ctx ))
7880
7981 // Get server types.
@@ -142,3 +144,109 @@ func serverTypeListBuilder(c *core.Command) *core.Command {
142144func serverTypeCategory (serverTypeName string ) (category string ) {
143145 return strings .Split (serverTypeName , "-" )[0 ]
144146}
147+
148+ func getCompatibleTypesBuilder (c * core.Command ) * core.Command {
149+ c .Interceptor = func (ctx context.Context , argsI interface {}, runner core.CommandRunner ) (interface {}, error ) {
150+ rawResp , err := runner (ctx , argsI )
151+ if err != nil {
152+ return rawResp , err
153+ }
154+ getCompatibleTypesResp := rawResp .(* instance.ServerCompatibleTypes )
155+
156+ request := argsI .(* instance.GetServerCompatibleTypesRequest )
157+ client := core .ExtractClient (ctx )
158+ api := instance .NewAPI (client )
159+ warnings := []error (nil )
160+
161+ // Get all server types to fill in the details in the response.
162+ listServersTypesResponse , err := api .ListServersTypes (& instance.ListServersTypesRequest {
163+ Zone : request .Zone ,
164+ }, scw .WithAllPages ())
165+ if err != nil {
166+ return nil , err
167+ }
168+
169+ // Build compatible types list with details
170+ compatibleServerTypesCustom := []* customServerType (nil )
171+ for _ , compatibleType := range getCompatibleTypesResp .CompatibleTypes {
172+ serverType , ok := listServersTypesResponse .Servers [compatibleType ]
173+ if ! ok {
174+ warnings = append (
175+ warnings ,
176+ fmt .Errorf ("could not find details on compatible type %q" , compatibleType ),
177+ )
178+ }
179+
180+ compatibleServerTypesCustom = append (compatibleServerTypesCustom , & customServerType {
181+ Name : compatibleType ,
182+ HourlyPrice : scw .NewMoneyFromFloat (
183+ float64 (serverType .HourlyPrice ),
184+ "EUR" ,
185+ 3 ,
186+ ),
187+ LocalVolumeMaxSize : serverType .VolumesConstraint .MaxSize ,
188+ CPU : serverType .Ncpus ,
189+ GPU : serverType .Gpu ,
190+ RAM : scw .Size (serverType .RAM ),
191+ Arch : serverType .Arch ,
192+ })
193+ }
194+
195+ // Get server's current type to fill in the details in the response
196+ server , err := api .GetServer (& instance.GetServerRequest {
197+ Zone : request .Zone ,
198+ ServerID : request .ServerID ,
199+ })
200+ if err != nil {
201+ return nil , err
202+ }
203+ currentServerType , ok := listServersTypesResponse .Servers [server .Server .CommercialType ]
204+ if ! ok {
205+ warnings = append (
206+ warnings ,
207+ fmt .Errorf (
208+ "could not find details on current type %q" ,
209+ server .Server .CommercialType ,
210+ ),
211+ )
212+ }
213+ currentServerTypeCustom := []* customServerType {
214+ {
215+ Name : server .Server .CommercialType ,
216+ HourlyPrice : scw .NewMoneyFromFloat (
217+ float64 (currentServerType .HourlyPrice ),
218+ "EUR" ,
219+ 3 ,
220+ ),
221+ LocalVolumeMaxSize : currentServerType .VolumesConstraint .MaxSize ,
222+ CPU : currentServerType .Ncpus ,
223+ GPU : currentServerType .Gpu ,
224+ RAM : scw .Size (currentServerType .RAM ),
225+ Arch : currentServerType .Arch ,
226+ },
227+ }
228+
229+ return & struct {
230+ CurrentServerType []* customServerType
231+ CompatibleServerTypes []* customServerType
232+ }{
233+ currentServerTypeCustom ,
234+ compatibleServerTypesCustom ,
235+ }, errors .Join (warnings ... )
236+ }
237+
238+ c .View = & core.View {
239+ Sections : []* core.ViewSection {
240+ {
241+ Title : "Current Server Type" ,
242+ FieldName : "CurrentServerType" ,
243+ },
244+ {
245+ Title : "Compatible Server Types" ,
246+ FieldName : "CompatibleServerTypes" ,
247+ },
248+ },
249+ }
250+
251+ return c
252+ }
0 commit comments