Skip to content

Commit c8fba41

Browse files
committed
Added helpers to manipulate the new user_data API (Fix #150)
1 parent 5a7b94d commit c8fba41

File tree

3 files changed

+140
-3
lines changed

3 files changed

+140
-3
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1128,7 +1128,7 @@ $ scw inspect myserver | jq '.[0].public_ip.address'
11281128
#### Features
11291129

11301130
* `scw info` now prints user/organization info from the API ([#142](https://github.com/scaleway/scaleway-cli/issues/130)
1131-
*
1131+
* Added helpers to manipulate new `user_data` API ([#150](https://github.com/scaleway/scaleway-cli/issues/150))
11321132

11331133
#### Fixes
11341134

pkg/api/api.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"crypto/tls"
1313
"encoding/json"
1414
"fmt"
15+
"io/ioutil"
1516
"net/http"
1617
"net/url"
1718
"os"
@@ -1322,6 +1323,98 @@ func (s *ScalewayAPI) GetBootscript(bootscriptID string) (*ScalewayBootscript, e
13221323
return &oneBootscript.Bootscript, nil
13231324
}
13241325

1326+
type ScalewayUserdatas struct {
1327+
UserData []string `json:"user_data"`
1328+
}
1329+
1330+
// GetUserdatas gets list of userdata for a server
1331+
func (s *ScalewayAPI) GetUserdatas(serverID string) (*ScalewayUserdatas, error) {
1332+
resp, err := s.GetResponse("servers/" + serverID + "/user_data")
1333+
if err != nil {
1334+
return nil, err
1335+
}
1336+
defer resp.Body.Close()
1337+
var userdatas ScalewayUserdatas
1338+
decoder := json.NewDecoder(resp.Body)
1339+
err = decoder.Decode(&userdatas)
1340+
if err != nil {
1341+
return nil, err
1342+
}
1343+
return &userdatas, nil
1344+
}
1345+
1346+
type ScalewayUserdata []byte
1347+
1348+
func (s *ScalewayUserdata) String() string {
1349+
return string(*s)
1350+
}
1351+
1352+
// GetUserdata gets a specific userdata for a server
1353+
func (s *ScalewayAPI) GetUserdata(serverID string, key string) (*ScalewayUserdata, error) {
1354+
var data ScalewayUserdata
1355+
var err error
1356+
resp, err := s.GetResponse("servers/" + serverID + "/user_data/" + key)
1357+
if err != nil {
1358+
return nil, err
1359+
}
1360+
if resp.StatusCode != 200 {
1361+
return nil, fmt.Errorf("no such user_data %q (%d)", key, resp.StatusCode)
1362+
}
1363+
1364+
defer resp.Body.Close()
1365+
data, err = ioutil.ReadAll(resp.Body)
1366+
return &data, err
1367+
}
1368+
1369+
// PatchUserdata sets a user data
1370+
func (s *ScalewayAPI) PatchUserdata(serverID string, key string, value []byte) error {
1371+
resource := fmt.Sprintf("servers/%s/user_data/%s", serverID, key)
1372+
uri := fmt.Sprintf("%s/%s", strings.TrimRight(s.APIUrl, "/"), resource)
1373+
payload := new(bytes.Buffer)
1374+
payload.Write(value)
1375+
1376+
req, err := http.NewRequest("PATCH", uri, payload)
1377+
if err != nil {
1378+
return err
1379+
}
1380+
1381+
req.Header.Set("X-Auth-Token", s.Token)
1382+
req.Header.Set("Content-Type", "text/plain")
1383+
1384+
curl, err := http2curl.GetCurlCommand(req)
1385+
if os.Getenv("SCW_SENSITIVE") != "1" {
1386+
log.Debug(s.HideAPICredentials(curl.String()))
1387+
} else {
1388+
log.Debug(curl.String())
1389+
}
1390+
1391+
resp, err := s.client.Do(req)
1392+
if err != nil {
1393+
return err
1394+
}
1395+
defer resp.Body.Close()
1396+
1397+
if resp.StatusCode == 204 {
1398+
return nil
1399+
}
1400+
1401+
return fmt.Errorf("cannot set user_data (%d)", resp.StatusCode)
1402+
}
1403+
1404+
// DeleteUserdata deletes a server user_data
1405+
func (s *ScalewayAPI) DeleteUserdata(serverID string, key string) error {
1406+
resp, err := s.DeleteResponse(fmt.Sprintf("servers/%s/user_data/%s", serverID, key))
1407+
if err != nil {
1408+
return err
1409+
}
1410+
1411+
// Succeed POST code
1412+
if resp.StatusCode == 204 {
1413+
return nil
1414+
}
1415+
return fmt.Errorf("cannot delete user_data (%d)", resp.StatusCode)
1416+
}
1417+
13251418
// GetTasks get the list of tasks from the ScalewayAPI
13261419
func (s *ScalewayAPI) GetTasks() (*[]ScalewayTask, error) {
13271420
query := url.Values{}

pkg/cli/x_userdata.go

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
package cli
66

7-
import "fmt"
7+
import (
8+
"fmt"
9+
"strings"
10+
)
811

912
var cmdUserdata = &Command{
1013
Exec: runUserdata,
@@ -35,7 +38,48 @@ func runUserdata(cmd *Command, args []string) error {
3538
return cmd.PrintShortUsage()
3639
}
3740

38-
fmt.Println("Not implemented")
41+
ctx := cmd.GetContext(args)
42+
serverID := ctx.API.GetServerID(args[0])
43+
44+
switch len(args) {
45+
case 1:
46+
// List userdata
47+
res, err := ctx.API.GetUserdatas(serverID)
48+
if err != nil {
49+
return err
50+
}
51+
for _, key := range res.UserData {
52+
fmt.Fprintln(ctx.Stdout, key)
53+
}
54+
default:
55+
parts := strings.Split(args[1], "=")
56+
key := parts[0]
57+
switch len(parts) {
58+
case 1:
59+
// Get userdatas
60+
res, err := ctx.API.GetUserdata(serverID, key)
61+
if err != nil {
62+
return err
63+
}
64+
fmt.Fprintf(ctx.Stdout, "%s\n", res.String())
65+
default:
66+
value := parts[1]
67+
if value != "" {
68+
// Set userdata
69+
err := ctx.API.PatchUserdata(serverID, key, []byte(value))
70+
if err != nil {
71+
return err
72+
}
73+
fmt.Fprintln(ctx.Stdout, key)
74+
} else {
75+
// Delete userdata
76+
err := ctx.API.DeleteUserdata(serverID, key)
77+
if err != nil {
78+
return err
79+
}
80+
}
81+
}
82+
}
3983

4084
return nil
4185
}

0 commit comments

Comments
 (0)