Skip to content

Commit c92d89b

Browse files
committed
Merge pull request #58 from scaleway/fix-57
Fix 57
2 parents c2021a9 + 452482c commit c92d89b

File tree

5 files changed

+154
-33
lines changed

5 files changed

+154
-33
lines changed

api.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -380,10 +380,23 @@ type ScalewayServer struct {
380380
Organization string `json:"organization,omitempty"`
381381
}
382382

383-
// ScalewayServerPathNameDefinition represents a Scaleway C1 server with only its name as field
384-
type ScalewayServerPathNameDefinition struct {
385-
// Name is the user-defined name of the server
386-
Name string `json:"name"`
383+
// ScalewayServerPatchDefinition represents a Scaleway C1 server with nullable fields (for PATCH)
384+
type ScalewayServerPatchDefinition struct {
385+
Name *string `json:"name,omitempty"`
386+
CreationDate *string `json:"creation_date,omitempty"`
387+
ModificationDate *string `json:"modification_date,omitempty"`
388+
Image *ScalewayImage `json:"image,omitempty"`
389+
DynamicIPRequired *bool `json:"dynamic_ip_required,omitempty"`
390+
PublicAddress *ScalewayIPAddress `json:"public_ip,omitempty"`
391+
State *string `json:"state,omitempty"`
392+
StateDetail *string `json:"state_detail,omitempty"`
393+
PrivateIP *string `json:"private_ip,omitempty"`
394+
Bootscript *ScalewayBootscript `json:"bootscript,omitempty"`
395+
Hostname *string `json:"hostname,omitempty"`
396+
Volumes *map[string]ScalewayVolume `json:"volumes,omitempty"`
397+
SecurityGroup *ScalewaySecurityGroup `json:"security_group,omitempty"`
398+
Organization *string `json:"organization,omitempty"`
399+
//Tags *[]string `json:"tags",omitempty`
387400
}
388401

389402
// ScalewayServerDefinition represents a Scaleway C1 server with image definition
@@ -682,8 +695,8 @@ func (s *ScalewayAPI) PostServer(definition ScalewayServerDefinition) (string, e
682695
return "", error
683696
}
684697

685-
// PatchServerName changes the name of the server
686-
func (s *ScalewayAPI) PatchServerName(serverID string, definition ScalewayServerPathNameDefinition) error {
698+
// PatchServer updates a server
699+
func (s *ScalewayAPI) PatchServer(serverID string, definition ScalewayServerPatchDefinition) error {
687700
resp, err := s.PatchResponse(fmt.Sprintf("servers/%s", serverID), definition)
688701
if err != nil {
689702
return err

api_helpers.go

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"fmt"
5+
"os"
56
"strings"
67
"sync"
78
"time"
@@ -40,6 +41,66 @@ type ScalewayResolvedIdentifier struct {
4041
Needle string
4142
}
4243

44+
// fillIdentifierCache fills the cache by fetching fro the API
45+
func fillIdentifierCache(api *ScalewayAPI) {
46+
log.Debugf("Filling the cache")
47+
var wg sync.WaitGroup
48+
wg.Add(5)
49+
go func() {
50+
api.GetServers(true, 0)
51+
wg.Done()
52+
}()
53+
go func() {
54+
api.GetImages()
55+
wg.Done()
56+
}()
57+
go func() {
58+
api.GetSnapshots()
59+
wg.Done()
60+
}()
61+
go func() {
62+
api.GetVolumes()
63+
wg.Done()
64+
}()
65+
go func() {
66+
api.GetBootscripts()
67+
wg.Done()
68+
}()
69+
wg.Wait()
70+
}
71+
72+
// getIdentifier returns a an identifier if the resolved needles only match one element, else, it exists the program
73+
func getIdentifier(api *ScalewayAPI, needle string) *ScalewayIdentifier {
74+
idents := resolveIdentifier(api, needle)
75+
76+
if len(idents) == 1 {
77+
return &idents[0]
78+
}
79+
if len(idents) == 0 {
80+
log.Fatalf("No such identifier: %s", needle)
81+
}
82+
log.Errorf("Too many candidates for %s (%d)", needle, len(idents))
83+
for _, identifier := range idents {
84+
// FIXME: also print the name
85+
log.Infof("- %s", identifier.Identifier)
86+
}
87+
os.Exit(1)
88+
return nil
89+
}
90+
91+
// resolveIdentifier resolves needle provided by the user
92+
func resolveIdentifier(api *ScalewayAPI, needle string) []ScalewayIdentifier {
93+
idents := api.Cache.LookUpIdentifiers(needle)
94+
if len(idents) > 0 {
95+
return idents
96+
}
97+
98+
fillIdentifierCache(api)
99+
100+
idents = api.Cache.LookUpIdentifiers(needle)
101+
return idents
102+
}
103+
43104
// resolveIdentifiers resolves needles provided by the user
44105
func resolveIdentifiers(api *ScalewayAPI, needles []string, out chan ScalewayResolvedIdentifier) {
45106
// first attempt, only lookup from the cache
@@ -57,29 +118,8 @@ func resolveIdentifiers(api *ScalewayAPI, needles []string, out chan ScalewayRes
57118
}
58119
// fill the cache by fetching from the API and resolve missing identifiers
59120
if len(unresolved) > 0 {
60-
var wg sync.WaitGroup
61-
wg.Add(5)
62-
go func() {
63-
api.GetServers(true, 0)
64-
wg.Done()
65-
}()
66-
go func() {
67-
api.GetImages()
68-
wg.Done()
69-
}()
70-
go func() {
71-
api.GetSnapshots()
72-
wg.Done()
73-
}()
74-
go func() {
75-
api.GetVolumes()
76-
wg.Done()
77-
}()
78-
go func() {
79-
api.GetBootscripts()
80-
wg.Done()
81-
}()
82-
wg.Wait()
121+
fillIdentifierCache(api)
122+
83123
for _, needle := range unresolved {
84124
idents := api.Cache.LookUpIdentifiers(needle)
85125
out <- ScalewayResolvedIdentifier{

cli.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ var commands = []*Command{
165165
cmdKill,
166166
cmdLogin,
167167
cmdLogs,
168+
cmdPatch,
168169
cmdPort,
169170
cmdPs,
170171
cmdRename,

patch.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
log "github.com/Sirupsen/logrus"
8+
)
9+
10+
var cmdPatch = &Command{
11+
Exec: runPatch,
12+
UsageLine: "_patch [OPTIONS] IDENTIFIER FIELD=VALUE",
13+
Description: "",
14+
Hidden: true,
15+
Help: "PATCH an object on the API",
16+
Examples: `
17+
$ scw _patch myserver state_detail=booted
18+
`,
19+
}
20+
21+
func init() {
22+
cmdPatch.Flag.BoolVar(&patchHelp, []string{"h", "-help"}, false, "Print usage")
23+
}
24+
25+
// Flags
26+
var patchHelp bool // -h, --help flag
27+
28+
func runPatch(cmd *Command, args []string) {
29+
if patchHelp {
30+
cmd.PrintUsage()
31+
}
32+
if len(args) != 2 {
33+
cmd.PrintShortUsage()
34+
}
35+
36+
// Parsing FIELD=VALUE
37+
updateParts := strings.Split(args[1], "=")
38+
if len(updateParts) != 2 {
39+
cmd.PrintShortUsage()
40+
}
41+
fieldName := updateParts[0]
42+
newValue := updateParts[1]
43+
44+
ident := getIdentifier(cmd.API, args[0])
45+
switch ident.Type {
46+
case IdentifierServer:
47+
var payload ScalewayServerPatchDefinition
48+
49+
switch fieldName {
50+
case "state_detail":
51+
payload.StateDetail = &newValue
52+
case "name":
53+
payload.Name = &newValue
54+
log.Warnf("Use 'scw rename instead'")
55+
default:
56+
log.Fatalf("'_patch server %s=' not implemented", fieldName)
57+
}
58+
59+
err := cmd.API.PatchServer(ident.Identifier, payload)
60+
if err != nil {
61+
log.Fatalf("Cannot rename server: %v", err)
62+
}
63+
default:
64+
log.Fatalf("_patch not implemented for this kind of object")
65+
}
66+
fmt.Println(ident.Identifier)
67+
}

rename.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ func runRename(cmd *Command, args []string) {
2626

2727
serverID := cmd.API.GetServerID(args[0])
2828

29-
var server ScalewayServerPathNameDefinition
30-
server.Name = args[1]
29+
var server ScalewayServerPatchDefinition
30+
server.Name = &args[1]
3131

32-
err := cmd.API.PatchServerName(serverID, server)
32+
err := cmd.API.PatchServer(serverID, server)
3333
if err != nil {
3434
log.Fatalf("Cannot rename server: %v", err)
3535
} else {
36-
cmd.API.Cache.InsertServer(serverID, server.Name)
36+
cmd.API.Cache.InsertServer(serverID, *server.Name)
3737
}
3838
}

0 commit comments

Comments
 (0)