Skip to content

Commit 87b1ae8

Browse files
authored
feat(instance): display server details for get-compatible-types (#4686)
1 parent b006eb9 commit 87b1ae8

File tree

2 files changed

+124
-11
lines changed

2 files changed

+124
-11
lines changed

internal/namespaces/instance/v1/custom.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ func GetCommands() *core.Commands {
8686

8787
cmds.MustFind("instance", "server-type", "list").Override(serverTypeListBuilder)
8888

89+
//
90+
// Get-Compatible-Types
91+
//
92+
cmds.MustFind("instance", "server", "get-compatible-types").Override(getCompatibleTypesBuilder)
93+
8994
//
9095
// IP
9196
//

internal/namespaces/instance/v1/custom_server_type.go

Lines changed: 119 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package instance
22

33
import (
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 {
142144
func 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

Comments
 (0)