Skip to content

Commit 8ac53ae

Browse files
feat(instance): generate user-data commands (#695)
1 parent c10a3c8 commit 8ac53ae

12 files changed

+2210
-122
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ require (
2020
github.com/mattn/go-colorable v0.1.2 // indirect
2121
github.com/mattn/go-isatty v0.0.9
2222
github.com/pkg/errors v0.9.1 // indirect
23-
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.5.0.20200211104822-047c88bb15c4
23+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.5.0.20200212160027-75ab2f6aeda3
2424
github.com/sergi/go-diff v1.0.0 // indirect
2525
github.com/spf13/cobra v0.0.5
2626
github.com/spf13/pflag v1.0.5 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNue
7474
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
7575
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.5.0.20200211104822-047c88bb15c4 h1:7MhGZPXmbEqx97kIrBA7Xen1obsqQPnR0HKErxh76S4=
7676
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.5.0.20200211104822-047c88bb15c4/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
77+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.5.0.20200212160027-75ab2f6aeda3 h1:BQb9gbsenI8ZwZmfN7O93VrlXW8eiDlL7Mz+glsK/os=
78+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.5.0.20200212160027-75ab2f6aeda3/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
7779
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
7880
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
7981
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=

internal/namespaces/instance/v1/custom.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,8 @@ func GetCommands() *core.Commands {
102102
//
103103
// User Data
104104
//
105-
cmds.Merge(core.NewCommands(
106-
userDataCommand(),
107-
userDataListCommand(),
108-
userDataSetCommand(),
109-
userDataDeleteCommand(),
110-
userDataGetCommand(),
111-
))
105+
cmds.MustFind("instance", "user-data", "set").Override(userDataSetBuilder)
106+
cmds.MustFind("instance", "user-data", "get").Override(userDataGetBuilder)
112107

113108
return cmds
114109
}

internal/namespaces/instance/v1/custom_user_data.go

Lines changed: 25 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -2,135 +2,46 @@ package instance
22

33
import (
44
"context"
5-
"reflect"
5+
"fmt"
6+
"net/http"
67

78
"github.com/scaleway/scaleway-cli/internal/core"
89
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
10+
"github.com/scaleway/scaleway-sdk-go/scw"
911
)
1012

1113
//
1214
// Commands
1315
//
1416

15-
func userDataCommand() *core.Command {
16-
return &core.Command{
17-
Namespace: "instance",
18-
Resource: "user-data",
17+
func userDataSetBuilder(c *core.Command) *core.Command {
18+
*c.ArgSpecs.GetByName("content.name") = core.ArgSpec{
19+
Name: "content",
20+
Short: "Content of the user data",
21+
Required: true,
1922
}
20-
}
2123

22-
func userDataListCommand() *core.Command {
23-
return &core.Command{
24-
Short: `List user data`,
25-
Long: `List user data for the given server.`,
26-
Namespace: "instance",
27-
Resource: "user-data",
28-
Verb: "list",
29-
ArgsType: reflect.TypeOf(instance.ListServerUserDataRequest{}),
30-
ArgSpecs: core.ArgSpecs{
31-
core.ZoneArgSpec(),
32-
{
33-
Name: "server-id",
34-
Short: `ID of a server`,
35-
Required: true,
36-
},
37-
},
38-
Run: func(ctx context.Context, argsI interface{}) (i interface{}, e error) {
39-
return instance.NewAPI(core.ExtractClient(ctx)).ListServerUserData(argsI.(*instance.ListServerUserDataRequest))
40-
},
41-
}
24+
c.ArgSpecs.DeleteByName("content.content-type")
25+
c.ArgSpecs.DeleteByName("content.content")
26+
return c
4227
}
4328

44-
func userDataDeleteCommand() *core.Command {
45-
return &core.Command{
46-
Short: `Delete user data by key`,
47-
Long: `Delete user data key for the given server.`,
48-
Namespace: "instance",
49-
Resource: "user-data",
50-
Verb: "delete",
51-
ArgsType: reflect.TypeOf(instance.DeleteServerUserDataRequest{}),
52-
ArgSpecs: core.ArgSpecs{
53-
core.ZoneArgSpec(),
54-
{
55-
Name: "server-id",
56-
Short: `ID of a server`,
57-
Required: true,
58-
},
59-
{
60-
Name: "key",
61-
Short: `Key of the user data`,
62-
Required: true,
63-
},
64-
},
65-
Run: func(ctx context.Context, argsI interface{}) (i interface{}, e error) {
66-
err := instance.NewAPI(core.ExtractClient(ctx)).DeleteServerUserData(argsI.(*instance.DeleteServerUserDataRequest))
67-
if err != nil {
68-
return nil, err
29+
func userDataGetBuilder(c *core.Command) *core.Command {
30+
originalRun := c.Run
31+
c.Run = func(ctx context.Context, argsI interface{}) (interface{}, error) {
32+
req := argsI.(*instance.GetServerUserDataRequest)
33+
res, err := originalRun(ctx, argsI)
34+
if err != nil {
35+
if resErr, ok := err.(*scw.ResponseError); ok {
36+
if resErr.StatusCode == http.StatusNotFound {
37+
return nil, fmt.Errorf("'%s' key does not exists", req.Key)
38+
}
6939
}
70-
return &core.SuccessResult{}, nil
71-
},
72-
}
73-
}
40+
return nil, err
41+
}
7442

75-
func userDataGetCommand() *core.Command {
76-
return &core.Command{
77-
Short: `Get user data key`,
78-
Long: `Get user data key for the given server.`,
79-
Namespace: "instance",
80-
Resource: "user-data",
81-
Verb: "get",
82-
ArgsType: reflect.TypeOf(instance.GetServerUserDataRequest{}),
83-
ArgSpecs: core.ArgSpecs{
84-
core.ZoneArgSpec(),
85-
{
86-
Name: "server-id",
87-
Short: `ID of a server`,
88-
Required: true,
89-
},
90-
{
91-
Name: "key",
92-
Short: `Key of the user data`,
93-
Required: true,
94-
},
95-
},
96-
Run: func(ctx context.Context, argsI interface{}) (i interface{}, e error) {
97-
return instance.NewAPI(core.ExtractClient(ctx)).GetServerUserData(argsI.(*instance.GetServerUserDataRequest))
98-
},
43+
return res, nil
9944
}
100-
}
10145

102-
func userDataSetCommand() *core.Command {
103-
return &core.Command{
104-
Short: `Set a user data`,
105-
Long: `Set a user data for the given server.`,
106-
Namespace: "instance",
107-
Resource: "user-data",
108-
Verb: "set",
109-
ArgsType: reflect.TypeOf(instance.SetServerUserDataRequest{}),
110-
ArgSpecs: core.ArgSpecs{
111-
core.ZoneArgSpec(),
112-
{
113-
Name: "server-id",
114-
Short: `ID of a server`,
115-
Required: true,
116-
},
117-
{
118-
Name: "key",
119-
Short: `Key of the user data`,
120-
Required: true,
121-
},
122-
{
123-
Name: "content",
124-
Short: `Content of the user data`,
125-
Required: true,
126-
},
127-
},
128-
Run: func(ctx context.Context, argsI interface{}) (i interface{}, e error) {
129-
err := instance.NewAPI(core.ExtractClient(ctx)).SetServerUserData(argsI.(*instance.SetServerUserDataRequest))
130-
if err != nil {
131-
return nil, err
132-
}
133-
return &core.SuccessResult{}, nil
134-
},
135-
}
46+
return c
13647
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package instance
2+
3+
import (
4+
"testing"
5+
6+
"github.com/scaleway/scaleway-cli/internal/core"
7+
)
8+
9+
func Test_UserDataGet(t *testing.T) {
10+
t.Run("Usage", core.Test(&core.TestConfig{
11+
Commands: GetCommands(),
12+
Cmd: "scw instance user-data get -h",
13+
Check: core.TestCheckCombine(
14+
core.TestCheckGolden(),
15+
core.TestCheckExitCode(0),
16+
),
17+
}))
18+
19+
t.Run("Get an existing key", core.Test(&core.TestConfig{
20+
BeforeFunc: func(ctx *core.BeforeFuncCtx) error {
21+
ctx.Meta["Server"] = ctx.ExecuteCmd("scw instance server create image=ubuntu_bionic stopped")
22+
ctx.ExecuteCmd("scw instance user-data set server-id={{.Server.ID}} key=happy content=true")
23+
return nil
24+
},
25+
Commands: GetCommands(),
26+
Cmd: "scw instance user-data get server-id={{.Server.ID}} key=happy",
27+
AfterFunc: deleteVanillaServer,
28+
Check: core.TestCheckCombine(
29+
core.TestCheckGolden(),
30+
core.TestCheckExitCode(0),
31+
),
32+
}))
33+
34+
t.Run("Get an nonexistent key", core.Test(&core.TestConfig{
35+
BeforeFunc: createVanillaServer,
36+
Commands: GetCommands(),
37+
Cmd: "scw instance user-data get server-id={{.Server.ID}} key=happy",
38+
AfterFunc: deleteVanillaServer,
39+
Check: core.TestCheckCombine(
40+
core.TestCheckGolden(),
41+
core.TestCheckExitCode(1),
42+
),
43+
}))
44+
}
45+
46+
func Test_UserDataSet(t *testing.T) {
47+
t.Run("Usage", core.Test(&core.TestConfig{
48+
Commands: GetCommands(),
49+
Cmd: "scw instance user-data set -h",
50+
Check: core.TestCheckCombine(
51+
core.TestCheckGolden(),
52+
core.TestCheckExitCode(0),
53+
),
54+
}))
55+
}

0 commit comments

Comments
 (0)