Skip to content

Commit

Permalink
feat(instance): add stocks in server-type list
Browse files Browse the repository at this point in the history
  • Loading branch information
Quentin Brosse committed Apr 2, 2020
1 parent 4750f7e commit 3da8792
Show file tree
Hide file tree
Showing 14 changed files with 134 additions and 114 deletions.
27 changes: 18 additions & 9 deletions internal/human/marshal_func.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,26 @@ func isMarshalable(t reflect.Type) bool {
(t.Kind() == reflect.Ptr && isMarshalable(t.Elem()))
}

// BindAttributesMarshalFunc will apply the Attributes bindings to the value i
func BindAttributesMarshalFunc(attributes Attributes) MarshalerFunc {
type EnumMarshalSpec struct {
// Attribute (mainly colors) to use.
Attribute color.Attribute

// Value is the value that will be printed for the given value.
Value string
}

type EnumMarshalSpecs map[interface{}]*EnumMarshalSpec

func EnumMarshalFunc(specs EnumMarshalSpecs) MarshalerFunc {
return func(i interface{}, opt *MarshalOpt) (s string, e error) {
s, _ = defaultMarshalerFunc(i, opt)
attribute, exist := attributes[i]
value, _ := defaultMarshalerFunc(i, opt)
spec, exist := specs[i]
if exist {
s = terminal.Style(s, attribute)
if spec.Value != "" {
value = spec.Value
}
value = terminal.Style(value, spec.Attribute)
}
return s, nil
return value, nil
}
}

// Attributes makes the binding between a value and a color.Attribute
type Attributes map[interface{}]color.Attribute
10 changes: 6 additions & 4 deletions internal/namespaces/instance/v1/custom.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func GetCommands() *core.Commands {
// Server
//
human.RegisterMarshalerFunc(instance.CreateServerResponse{}, marshallNestedField("Server"))
human.RegisterMarshalerFunc(instance.ServerState(0), serverStateMarshalerFunc)
human.RegisterMarshalerFunc(instance.ServerState(0), human.EnumMarshalFunc(serverStateMarshalSpecs))
human.RegisterMarshalerFunc(instance.ServerLocation{}, serverLocationMarshalerFunc)
human.RegisterMarshalerFunc([]*instance.Server{}, serversMarshalerFunc)
human.RegisterMarshalerFunc(instance.GetServerResponse{}, getServerResponseMarshalerFunc)
Expand All @@ -46,6 +46,8 @@ func GetCommands() *core.Commands {
//
// Server-Type
//
human.RegisterMarshalerFunc(instance.ServerTypesAvailability(""), human.EnumMarshalFunc(serverTypesAvailabilityMarshalSpecs))

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

//
Expand All @@ -70,15 +72,15 @@ func GetCommands() *core.Commands {
// Volume
//
human.RegisterMarshalerFunc(instance.CreateVolumeResponse{}, marshallNestedField("Volume"))
human.RegisterMarshalerFunc(instance.VolumeState(0), human.BindAttributesMarshalFunc(volumeStateAttributes))
human.RegisterMarshalerFunc(instance.VolumeState(0), human.EnumMarshalFunc(volumeStateMarshalSpecs))
human.RegisterMarshalerFunc(instance.VolumeSummary{}, volumeSummaryMarshalerFunc)
human.RegisterMarshalerFunc(map[string]*instance.Volume{}, volumeMapMarshalerFunc)

//
// Security Group
//
human.RegisterMarshalerFunc(instance.CreateSecurityGroupResponse{}, marshallNestedField("SecurityGroup"))
human.RegisterMarshalerFunc(instance.SecurityGroupPolicy(0), human.BindAttributesMarshalFunc(securityGroupPolicyAttribute))
human.RegisterMarshalerFunc(instance.SecurityGroupPolicy(0), human.EnumMarshalFunc(securityGroupPolicyMarshalSpecs))

cmds.MustFind("instance", "security-group", "get").Override(securityGroupGetBuilder)
cmds.MustFind("instance", "security-group", "delete").Override(securityGroupDeleteBuilder)
Expand All @@ -92,7 +94,7 @@ func GetCommands() *core.Commands {
// Security Group Rule
//
human.RegisterMarshalerFunc(instance.CreateSecurityGroupRuleResponse{}, marshallNestedField("Rule"))
human.RegisterMarshalerFunc(instance.SecurityGroupRuleAction(0), human.BindAttributesMarshalFunc(securityGroupRuleActionAttribute))
human.RegisterMarshalerFunc(instance.SecurityGroupRuleAction(0), human.EnumMarshalFunc(securityGroupRuleActionMarshalSpecs))

//
// Placement Group
Expand Down
12 changes: 6 additions & 6 deletions internal/namespaces/instance/v1/custom_security_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ import (
//

var (
securityGroupPolicyAttribute = human.Attributes{
instance.SecurityGroupPolicyDrop: color.FgRed,
instance.SecurityGroupPolicyAccept: color.FgGreen,
securityGroupPolicyMarshalSpecs = human.EnumMarshalSpecs{
instance.SecurityGroupPolicyDrop: &human.EnumMarshalSpec{Attribute: color.FgRed},
instance.SecurityGroupPolicyAccept: &human.EnumMarshalSpec{Attribute: color.FgGreen},
}

securityGroupRuleActionAttribute = human.Attributes{
instance.SecurityGroupRuleActionDrop: color.FgRed,
instance.SecurityGroupRuleActionAccept: color.FgGreen,
securityGroupRuleActionMarshalSpecs = human.EnumMarshalSpecs{
instance.SecurityGroupRuleActionDrop: &human.EnumMarshalSpec{Attribute: color.FgRed},
instance.SecurityGroupRuleActionAccept: &human.EnumMarshalSpec{Attribute: color.FgGreen},
}
)

Expand Down
23 changes: 0 additions & 23 deletions internal/namespaces/instance/v1/custom_security_group_rule.go

This file was deleted.

19 changes: 11 additions & 8 deletions internal/namespaces/instance/v1/custom_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import (
"time"

"github.com/fatih/color"

"github.com/hashicorp/go-multierror"
"github.com/scaleway/scaleway-cli/internal/core"
"github.com/scaleway/scaleway-cli/internal/human"
"github.com/scaleway/scaleway-cli/internal/interactive"
"github.com/scaleway/scaleway-cli/internal/terminal"
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
"github.com/scaleway/scaleway-sdk-go/logger"
"github.com/scaleway/scaleway-sdk-go/scw"
Expand All @@ -28,14 +28,17 @@ const (
// Marshalers
//

// serverStateMarshalerFunc marshals a instance.ServerState.
func serverStateMarshalerFunc(i interface{}, opt *human.MarshalOpt) (string, error) {
// The Scaleway console shows "archived" for a stopped server.
if i.(instance.ServerState) == instance.ServerStateStopped {
return terminal.Style("archived", color.Faint), nil
// serverStateMarshalSpecs allows to override the displayed instance.ServerState.
var (
serverStateMarshalSpecs = human.EnumMarshalSpecs{
instance.ServerStateRunning: &human.EnumMarshalSpec{Attribute: color.FgGreen},
instance.ServerStateStopped: &human.EnumMarshalSpec{Attribute: color.Faint, Value: "archived"},
instance.ServerStateStoppedInPlace: &human.EnumMarshalSpec{Attribute: color.Faint},
instance.ServerStateStarting: &human.EnumMarshalSpec{Attribute: color.FgBlue},
instance.ServerStateStopping: &human.EnumMarshalSpec{Attribute: color.FgBlue},
instance.ServerStateLocked: &human.EnumMarshalSpec{Attribute: color.FgRed},
}
return human.BindAttributesMarshalFunc(serverStateAttributes)(i, opt)
}
)

// serverLocationMarshalerFunc marshals a instance.ServerLocation.
func serverLocationMarshalerFunc(i interface{}, opt *human.MarshalOpt) (string, error) {
Expand Down
57 changes: 43 additions & 14 deletions internal/namespaces/instance/v1/custom_server_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,25 @@ import (
"sort"
"strings"

"github.com/fatih/color"
"github.com/scaleway/scaleway-cli/internal/core"
"github.com/scaleway/scaleway-cli/internal/human"
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
)

//
// Marshalers
//

var (
serverTypesAvailabilityMarshalSpecs = human.EnumMarshalSpecs{
instance.ServerTypesAvailabilityAvailable: &human.EnumMarshalSpec{Attribute: color.FgGreen},
instance.ServerTypesAvailabilityScarce: &human.EnumMarshalSpec{Attribute: color.Faint, Value: "low stock"},
instance.ServerTypesAvailabilityShortage: &human.EnumMarshalSpec{Attribute: color.FgRed, Value: "out of stock"},
}
)

//
// Builders
//
Expand All @@ -33,30 +47,44 @@ func serverTypeListBuilder(c *core.Command) *core.Command {
"X64-60GB": {},
}

originalRun := c.Run

c.Run = func(ctx context.Context, argsI interface{}) (interface{}, error) {
type customServerType struct {
Name string `json:"name"`
MonthlyPrice *scw.Money `json:"monthly_price"`
HourlyPrice *scw.Money `json:"hourly_price"`
LocalVolumeSize scw.Size `json:"local_volume_size"`
CPU uint32 `json:"cpu"`
GPU *uint64 `json:"gpu"`
RAM scw.Size `json:"ram"`
Arch instance.Arch `json:"arch"`
Name string `json:"name"`
MonthlyPrice *scw.Money `json:"monthly_price"`
HourlyPrice *scw.Money `json:"hourly_price"`
LocalVolumeSize scw.Size `json:"local_volume_size"`
CPU uint32 `json:"cpu"`
GPU *uint64 `json:"gpu"`
RAM scw.Size `json:"ram"`
Arch instance.Arch `json:"arch"`
Availability instance.ServerTypesAvailability `json:"availability"`
}

originalRes, err := originalRun(ctx, argsI)
api := instance.NewAPI(core.ExtractClient(ctx))

// Get server types.
request := argsI.(*instance.ListServersTypesRequest)
listServersTypesResponse, err := api.ListServersTypes(request)
if err != nil {
return nil, err
}

listServersTypesResponse := originalRes.(*instance.ListServersTypesResponse)
serverTypes := []*customServerType(nil)

for name, serverType := range listServersTypesResponse.Servers {
// Get server availabilities.
serverAvailabilities := make(map[string]instance.ServerTypesAvailability)
availabilitiesResponse, err := api.GetServerTypesAvailability(&instance.GetServerTypesAvailabilityRequest{})
if err != nil {
// Do nothing and show degraded results.
} else {
serverAvailabilities = availabilitiesResponse.Servers
}

// Remove me
serverAvailabilities["ARM64-2GB"] = instance.ServerTypesAvailabilityAvailable // available green
serverAvailabilities["ARM64-4GB"] = instance.ServerTypesAvailabilityScarce // low Stock orange
serverAvailabilities["ARM64-8GB"] = instance.ServerTypesAvailabilityShortage // temporarily out of stock red

for name, serverType := range listServersTypesResponse.Servers {
_, isDeprecated := deprecatedNames[name]
if isDeprecated {
continue
Expand All @@ -71,6 +99,7 @@ func serverTypeListBuilder(c *core.Command) *core.Command {
GPU: serverType.Gpu,
RAM: scw.Size(serverType.RAM),
Arch: serverType.Arch,
Availability: serverAvailabilities[name],
})
}

Expand Down
2 changes: 1 addition & 1 deletion internal/namespaces/instance/v1/custom_server_type_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"github.com/scaleway/scaleway-cli/internal/core"
)

func Test_serverTypeListBuilder(t *testing.T) {
func Test_ServerTypeList(t *testing.T) {
t.Run("server-type list", core.Test(&core.TestConfig{
Commands: GetCommands(),
Cmd: "scw instance server-type list",
Expand Down
6 changes: 3 additions & 3 deletions internal/namespaces/instance/v1/custom_volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import (
//

var (
volumeStateAttributes = human.Attributes{
instance.VolumeStateError: color.FgRed,
instance.VolumeStateAvailable: color.FgGreen,
volumeStateMarshalSpecs = human.EnumMarshalSpecs{
instance.VolumeStateError: &human.EnumMarshalSpec{Attribute: color.FgRed},
instance.VolumeStateAvailable: &human.EnumMarshalSpec{Attribute: color.FgGreen},
}
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
NAME MONTHLY PRICE HOURLY PRICE LOCAL VOLUME SIZE CPU GPU RAM ARCH
ARM64-2GB € 2.99 € 0.006 50 GB 4 2.0 GiB arm64
ARM64-4GB € 5.99 € 0.012 100 GB 6 4.0 GiB arm64
ARM64-8GB € 11.99 € 0.024 200 GB 8 8.0 GiB arm64
ARM64-16GB € 34.99 € 0.07 200 GB 16 16 GiB arm64
ARM64-32GB € 69.99 € 0.14 300 GB 32 32 GiB arm64
ARM64-64GB € 139.99 € 0.28 400 GB 48 64 GiB arm64
ARM64-128GB € 279.99 € 0.56 500 GB 64 128 GiB arm64
C1 € 2.99 € 0.006 50 GB 4 2.0 GiB arm
C2L € 23.99 € 0.048 50 GB 8 32 GiB x86_64
C2M € 17.99 € 0.036 50 GB 8 16 GiB x86_64
C2S € 11.99 € 0.024 50 GB 4 8.0 GiB x86_64
DEV1-S € 2.99 € 0.006 20 GB 2 2.0 GiB x86_64
DEV1-M € 7.99 € 0.016 40 GB 3 4.0 GiB x86_64
DEV1-L € 15.99 € 0.032 80 GB 4 8.0 GiB x86_64
DEV1-XL € 23.99 € 0.048 120 GB 4 12 GiB x86_64
GP1-XS € 39.00 € 0.078 150 GB 4 16 GiB x86_64
GP1-S € 79.00 € 0.158 300 GB 8 32 GiB x86_64
GP1-M € 159.00 € 0.318 600 GB 16 64 GiB x86_64
GP1-L € 299.00 € 0.598 600 GB 32 128 GiB x86_64
GP1-XL € 569.00 € 1.138 600 GB 48 256 GiB x86_64
RENDER-S € 499.99 € 1.00 400 GB 10 1 45 GiB x86_64
NAME MONTHLY PRICE HOURLY PRICE LOCAL VOLUME SIZE CPU GPU RAM ARCH AVAILABILITY
ARM64-2GB € 2.99 € 0.006 50 GB 4 2.0 GiB arm64 available
ARM64-4GB € 5.99 € 0.012 100 GB 6 4.0 GiB arm64 low stock
ARM64-8GB € 11.99 € 0.024 200 GB 8 8.0 GiB arm64 out of stock
ARM64-16GB € 34.99 € 0.07 200 GB 16 16 GiB arm64 available
ARM64-32GB € 69.99 € 0.14 300 GB 32 32 GiB arm64 available
ARM64-64GB € 139.99 € 0.28 400 GB 48 64 GiB arm64 available
ARM64-128GB € 279.99 € 0.56 500 GB 64 128 GiB arm64 available
C1 € 2.99 € 0.006 50 GB 4 2.0 GiB arm available
C2L € 23.99 € 0.048 50 GB 8 32 GiB x86_64 available
C2M € 17.99 € 0.036 50 GB 8 16 GiB x86_64 available
C2S € 11.99 € 0.024 50 GB 4 8.0 GiB x86_64 available
DEV1-S € 2.99 € 0.006 20 GB 2 2.0 GiB x86_64 available
DEV1-M € 7.99 € 0.016 40 GB 3 4.0 GiB x86_64 available
DEV1-L € 15.99 € 0.032 80 GB 4 8.0 GiB x86_64 available
DEV1-XL € 23.99 € 0.048 120 GB 4 12 GiB x86_64 available
GP1-XS € 39.00 € 0.078 150 GB 4 16 GiB x86_64 available
GP1-S € 79.00 € 0.158 300 GB 8 32 GiB x86_64 available
GP1-M € 159.00 € 0.318 600 GB 16 64 GiB x86_64 available
GP1-L € 299.00 € 0.598 600 GB 32 128 GiB x86_64 available
GP1-XL € 569.00 € 1.138 600 GB 48 256 GiB x86_64 available
RENDER-S € 499.99 € 1.00 400 GB 10 1 45 GiB x86_64 available
6 changes: 3 additions & 3 deletions internal/namespaces/k8s/v1/custom.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ func GetCommands() *core.Commands {
k8sKubeconfigUninstallCommand(),
))

human.RegisterMarshalerFunc(k8s.ClusterStatus(0), human.BindAttributesMarshalFunc(clusterStatusAttributes))
human.RegisterMarshalerFunc(k8s.PoolStatus(0), human.BindAttributesMarshalFunc(poolStatusAttributes))
human.RegisterMarshalerFunc(k8s.NodeStatus(0), human.BindAttributesMarshalFunc(nodeStatusAttributes))
human.RegisterMarshalerFunc(k8s.ClusterStatus(0), human.EnumMarshalFunc(clusterStatusMarshalSpecs))
human.RegisterMarshalerFunc(k8s.PoolStatus(0), human.EnumMarshalFunc(poolStatusMarshalSpecs))
human.RegisterMarshalerFunc(k8s.NodeStatus(0), human.EnumMarshalFunc(nodeStatusMarshalSpecs))

cmds.MustFind("k8s", "cluster", "list-available-versions").Override(clusterAvailableVersionsListBuilder)
cmds.MustFind("k8s", "cluster", "create").Override(clusterCreateBuilder)
Expand Down
12 changes: 6 additions & 6 deletions internal/namespaces/k8s/v1/custom_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ const (

// clusterStatusMarshalerFunc marshals a k8s.ClusterStatus.
var (
clusterStatusAttributes = human.Attributes{
k8s.ClusterStatusCreating: color.FgBlue,
k8s.ClusterStatusReady: color.FgGreen,
k8s.ClusterStatusPoolRequired: color.FgRed,
k8s.ClusterStatusLocked: color.FgRed,
k8s.ClusterStatusUpdating: color.FgBlue,
clusterStatusMarshalSpecs = human.EnumMarshalSpecs{
k8s.ClusterStatusCreating: &human.EnumMarshalSpec{Attribute: color.FgBlue},
k8s.ClusterStatusReady: &human.EnumMarshalSpec{Attribute: color.FgGreen},
k8s.ClusterStatusPoolRequired: &human.EnumMarshalSpec{Attribute: color.FgRed},
k8s.ClusterStatusLocked: &human.EnumMarshalSpec{Attribute: color.FgRed},
k8s.ClusterStatusUpdating: &human.EnumMarshalSpec{Attribute: color.FgBlue},
}
)

Expand Down
16 changes: 8 additions & 8 deletions internal/namespaces/k8s/v1/custom_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ const (
)

var (
// nodeStatusAttributes allows to override the displayed status color
nodeStatusAttributes = human.Attributes{
k8s.NodeStatusCreating: color.FgBlue,
k8s.NodeStatusRebooting: color.FgBlue,
k8s.NodeStatusReady: color.FgGreen,
k8s.NodeStatusNotReady: color.FgYellow,
k8s.NodeStatusCreationError: color.FgRed,
k8s.NodeStatusLocked: color.FgRed,
// nodeStatusMarshalSpecs allows to override the displayed status color
nodeStatusMarshalSpecs = human.EnumMarshalSpecs{
k8s.NodeStatusCreating: &human.EnumMarshalSpec{Attribute: color.FgBlue},
k8s.NodeStatusRebooting: &human.EnumMarshalSpec{Attribute: color.FgBlue},
k8s.NodeStatusReady: &human.EnumMarshalSpec{Attribute: color.FgGreen},
k8s.NodeStatusNotReady: &human.EnumMarshalSpec{Attribute: color.FgYellow},
k8s.NodeStatusCreationError: &human.EnumMarshalSpec{Attribute: color.FgRed},
k8s.NodeStatusLocked: &human.EnumMarshalSpec{Attribute: color.FgRed},
}
)

Expand Down
Loading

0 comments on commit 3da8792

Please sign in to comment.