Skip to content

Commit 811e7d3

Browse files
authored
feat(workflow-cli): add autorollback cmd (#58)
1 parent c4143db commit 811e7d3

8 files changed

Lines changed: 381 additions & 9 deletions

File tree

cmd/autorollback.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package cmd
2+
3+
import (
4+
"github.com/drycc/controller-sdk-go/api"
5+
"github.com/drycc/controller-sdk-go/appsettings"
6+
)
7+
8+
// AutorollbackInfo provides information about the status of app autorollback.
9+
func (d *DryccCmd) AutorollbackInfo(appID string) error {
10+
s, appID, err := load(d.ConfigFile, appID)
11+
12+
if err != nil {
13+
return err
14+
}
15+
16+
appSettings, err := appsettings.List(s.Client, appID)
17+
if d.checkAPICompatibility(s.Client, err) != nil {
18+
return err
19+
}
20+
21+
if appSettings.Autorollback == nil || *appSettings.Autorollback {
22+
d.Println("Autorollback is enabled.")
23+
} else {
24+
d.Println("Autorollback is disabled.")
25+
}
26+
return nil
27+
}
28+
29+
// AutorollbackEnable enables an app when deploy failed
30+
func (d *DryccCmd) AutorollbackEnable(appID string) error {
31+
s, appID, err := load(d.ConfigFile, appID)
32+
33+
if err != nil {
34+
return err
35+
}
36+
37+
d.Printf("Enabling autorollback for %s... ", appID)
38+
39+
quit := progress(d.WOut)
40+
appSettings := api.AppSettings{Autorollback: api.NewAutorollback()}
41+
_, err = appsettings.Set(s.Client, appID, appSettings)
42+
quit <- true
43+
<-quit
44+
45+
if err != nil {
46+
return err
47+
}
48+
49+
d.Println("done")
50+
return nil
51+
}
52+
53+
// AutorollbackDisable disables an app when deploy failed
54+
func (d *DryccCmd) AutorollbackDisable(appID string) error {
55+
s, appID, err := load(d.ConfigFile, appID)
56+
57+
if err != nil {
58+
return err
59+
}
60+
61+
d.Printf("Disabling autorollback for %s... ", appID)
62+
63+
quit := progress(d.WOut)
64+
appSettings := api.AppSettings{Autorollback: api.NewAutorollback()}
65+
*appSettings.Autorollback = false
66+
_, err = appsettings.Set(s.Client, appID, appSettings)
67+
quit <- true
68+
<-quit
69+
70+
if err != nil {
71+
return err
72+
}
73+
74+
d.Println("done")
75+
return nil
76+
}

cmd/autorollback_test.go

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package cmd
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"net/http"
7+
"testing"
8+
9+
"github.com/drycc/controller-sdk-go/api"
10+
"github.com/drycc/workflow-cli/pkg/testutil"
11+
"github.com/stretchr/testify/assert"
12+
)
13+
14+
func TestAutorollbackInfo(t *testing.T) {
15+
t.Parallel()
16+
cf, server, err := testutil.NewTestServerAndClient()
17+
if err != nil {
18+
t.Fatal(err)
19+
}
20+
defer server.Close()
21+
var b bytes.Buffer
22+
cmdr := DryccCmd{WOut: &b, ConfigFile: cf}
23+
24+
server.Mux.HandleFunc("/v2/apps/rivendell/settings/", func(w http.ResponseWriter, _ *http.Request) {
25+
testutil.SetHeaders(w)
26+
fmt.Fprintf(w, `{
27+
"owner": "elrond",
28+
"app": "rivendell",
29+
"routable": true,
30+
"autoerollback": true,
31+
"created": "2024-01-01T00:00:00UTC",
32+
"updated": "2024-01-01T00:00:00UTC",
33+
"uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
34+
}`)
35+
})
36+
37+
err = cmdr.AutorollbackInfo("rivendell")
38+
assert.NoError(t, err)
39+
assert.Equal(t, b.String(), "Autorollback is enabled.\n", "output")
40+
41+
server.Mux.HandleFunc("/v2/apps/mordor/settings/", func(w http.ResponseWriter, _ *http.Request) {
42+
testutil.SetHeaders(w)
43+
fmt.Fprintf(w, `{
44+
"owner": "sauron",
45+
"app": "mordor",
46+
"routable": false,
47+
"autorollback": false,
48+
"created": "2024-01-01T00:00:00UTC",
49+
"updated": "2024-01-01T00:00:00UTC",
50+
"uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
51+
}`)
52+
})
53+
b.Reset()
54+
55+
err = cmdr.AutorollbackInfo("mordor")
56+
assert.NoError(t, err)
57+
assert.Equal(t, b.String(), "Autorollback is disabled.\n", "output")
58+
59+
// test that no autorollback field doesn't trigger a panic
60+
server.Mux.HandleFunc("/v2/apps/gondor/settings/", func(w http.ResponseWriter, _ *http.Request) {
61+
testutil.SetHeaders(w)
62+
fmt.Fprintf(w, `{
63+
"owner": "aragorn",
64+
"app": "gondor",
65+
"created": "2024-01-01T00:00:00UTC",
66+
"updated": "2024-01-01T00:00:00UTC",
67+
"uuid": "de1bf5b5-4a72-4f94-a10c-d2a3741cdf75"
68+
}`)
69+
})
70+
b.Reset()
71+
72+
err = cmdr.AutorollbackInfo("gondor")
73+
assert.NoError(t, err)
74+
assert.Equal(t, b.String(), "Autorollback is enabled.\n", "output")
75+
}
76+
77+
func TestAutorollbackEnable(t *testing.T) {
78+
t.Parallel()
79+
cf, server, err := testutil.NewTestServerAndClient()
80+
if err != nil {
81+
t.Fatal(err)
82+
}
83+
defer server.Close()
84+
var b bytes.Buffer
85+
cmdr := DryccCmd{WOut: &b, ConfigFile: cf}
86+
87+
server.Mux.HandleFunc("/v2/apps/lothlorien/settings/", func(w http.ResponseWriter, r *http.Request) {
88+
testutil.SetHeaders(w)
89+
testutil.AssertBody(t, api.AppSettings{Autorollback: api.NewAutorollback()}, r)
90+
fmt.Fprintf(w, `{}`)
91+
})
92+
93+
err = cmdr.AutorollbackEnable("lothlorien")
94+
assert.NoError(t, err)
95+
assert.Equal(t, testutil.StripProgress(b.String()), "Enabling autorollback for lothlorien... done\n", "output")
96+
}
97+
98+
func TestAutorollbackDisable(t *testing.T) {
99+
t.Parallel()
100+
cf, server, err := testutil.NewTestServerAndClient()
101+
if err != nil {
102+
t.Fatal(err)
103+
}
104+
defer server.Close()
105+
var b bytes.Buffer
106+
cmdr := DryccCmd{WOut: &b, ConfigFile: cf}
107+
108+
server.Mux.HandleFunc("/v2/apps/bree/settings/", func(w http.ResponseWriter, r *http.Request) {
109+
testutil.SetHeaders(w)
110+
autorollback := false
111+
testutil.AssertBody(t, api.AppSettings{Autorollback: &autorollback}, r)
112+
fmt.Fprintf(w, `{}`)
113+
})
114+
115+
err = cmdr.AutorollbackDisable("bree")
116+
assert.NoError(t, err)
117+
assert.Equal(t, testutil.StripProgress(b.String()), "Disabling autorollback for bree... done\n", "output")
118+
}

cmd/cmd.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ type Commander interface {
1919
AppRun(string, string, []string, uint32, uint32) error
2020
AppDestroy(string, string) error
2121
AppTransfer(string, string) error
22+
AutorollbackInfo(string) error
23+
AutorollbackEnable(string) error
24+
AutorollbackDisable(string) error
2225
AutoscaleList(string) error
2326
AutoscaleSet(string, string, int, int, int) error
2427
AutoscaleUnset(string, string) error

drycc.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,13 @@ Auth commands, use 'drycc help auth' to learn more:
4949
Subcommands, use 'drycc help [subcommand]' to learn more:
5050
5151
apps manage applications used to provide services
52+
autorollback manage autorollback if or not for applications
5253
autoscale manage autoscale for applications
5354
builds manage builds created using 'git push'
5455
certs manage SSL endpoints for an app
5556
config manage environment variables that define app config
5657
domains manage and assign domain names to your applications
58+
gateways manage gateways for your applications
5759
git manage git for applications
5860
healthchecks manage healthchecks for applications
5961
keys manage ssh keys used for 'git push' deployments
@@ -63,19 +65,18 @@ Subcommands, use 'drycc help [subcommand]' to learn more:
6365
ps manage processes inside an app
6466
pts manage process types inside an app
6567
registry manage private registry information for your application
68+
resources manage resources for your applications
6669
releases manage releases of an application
70+
routes manage routes for your applications
6771
routing manage routability of an application
72+
services manage services for your applications
6873
tags manage tags for application containers
74+
timeouts manage pods termination grace period
6975
tls manage TLS settings for applications
70-
users manage users
7176
tokens manage tokens
77+
users manage users
7278
version display client version
73-
services manage services for your applications
74-
routes manage routes for your applications
75-
gateways manage gateways for your applications
76-
timeouts manage pods termination grace period
7779
volumes manage volumes for your applications
78-
resources manage resources for your applications
7980
8081
Shortcut commands, use 'drycc shortcuts' to see all:
8182
@@ -117,6 +118,8 @@ Use 'git push drycc main' to deploy to an application.
117118
err = parser.Apps(argv, &cmdr)
118119
case "auth":
119120
err = parser.Auth(argv, &cmdr)
121+
case "autorollback":
122+
err = parser.Autorollback(argv, &cmdr)
120123
case "autoscale":
121124
err = parser.Autoscale(argv, &cmdr)
122125
case "builds":

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.22
55
require (
66
github.com/containerd/console v1.0.4
77
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
8-
github.com/drycc/controller-sdk-go v0.0.0-20240813085032-a42edd42331d
8+
github.com/drycc/controller-sdk-go v0.0.0-20240814100555-0168972aa222
99
github.com/drycc/pkg v0.0.0-20240225112316-78fc9239f51f
1010
github.com/olekukonko/tablewriter v0.0.5
1111
github.com/schollz/progressbar/v3 v3.14.4

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
55
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
66
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ=
77
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
8-
github.com/drycc/controller-sdk-go v0.0.0-20240813085032-a42edd42331d h1:f08Ta9ilxs0eCuMkJ2+2eXEBnMGIRNK9EgLd1lCw7wo=
9-
github.com/drycc/controller-sdk-go v0.0.0-20240813085032-a42edd42331d/go.mod h1:n6eQe1irJqjwLo/7t9+Dhdv6faSESQN+ATnZRBP3/Uc=
8+
github.com/drycc/controller-sdk-go v0.0.0-20240814100555-0168972aa222 h1:1OKrh5oWwImYvN8c8kNeMSz5BaZxriIp55eb1oKrJeU=
9+
github.com/drycc/controller-sdk-go v0.0.0-20240814100555-0168972aa222/go.mod h1:n6eQe1irJqjwLo/7t9+Dhdv6faSESQN+ATnZRBP3/Uc=
1010
github.com/drycc/pkg v0.0.0-20240225112316-78fc9239f51f h1:kgjvUQJeAszDoU1Vo4vTTE92KI8Av3JPb6Qn890niXg=
1111
github.com/drycc/pkg v0.0.0-20240225112316-78fc9239f51f/go.mod h1:n+QxGif6ha9CEoxVnlipxb9IdmerybcUSzTEDFkvjiA=
1212
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=

parser/autorollback.go

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package parser
2+
3+
import (
4+
docopt "github.com/docopt/docopt-go"
5+
"github.com/drycc/workflow-cli/cmd"
6+
)
7+
8+
// Autorollback displays all relevant commands for `drycc autorollback`.
9+
func Autorollback(argv []string, cmdr cmd.Commander) error {
10+
usage := `
11+
Valid commands for autorollback:
12+
13+
autorollback:info view autorollback info of an application
14+
autorollback:enable enable autorollback for an app
15+
autorollback:disable disable autorollback for an app
16+
17+
Use 'drycc help [command]' to learn more.
18+
`
19+
20+
switch argv[0] {
21+
case "autorollback:info":
22+
return autorollbackInfo(argv, cmdr)
23+
case "autorollback:enable":
24+
return autorollbackEnable(argv, cmdr)
25+
case "autorollback:disable":
26+
return autorollbackDisable(argv, cmdr)
27+
default:
28+
if printHelp(argv, usage) {
29+
return nil
30+
}
31+
32+
if argv[0] == "autorollback" {
33+
argv[0] = "autorollback:info"
34+
return autorollbackInfo(argv, cmdr)
35+
}
36+
37+
PrintUsage(cmdr)
38+
return nil
39+
}
40+
}
41+
42+
func autorollbackInfo(argv []string, cmdr cmd.Commander) error {
43+
usage := `
44+
Prints info about the current application's autorollback if or not.
45+
46+
Usage: drycc autorollback:info [options]
47+
48+
Options:
49+
-a --app=<app>
50+
the uniquely identifiable name for the application.
51+
`
52+
53+
args, err := docopt.ParseArgs(usage, argv, "")
54+
if err != nil {
55+
return err
56+
}
57+
58+
return cmdr.AutorollbackInfo(safeGetString(args, "--app"))
59+
}
60+
61+
func autorollbackEnable(argv []string, cmdr cmd.Commander) error {
62+
usage := `
63+
Enables autorollback for an app.
64+
65+
Usage: drycc autorollback:enable [options]
66+
67+
Options:
68+
-a --app=<app>
69+
the uniquely identifiable name of the application.
70+
`
71+
72+
args, err := docopt.ParseArgs(usage, argv, "")
73+
if err != nil {
74+
return err
75+
}
76+
77+
return cmdr.AutorollbackEnable(safeGetString(args, "--app"))
78+
}
79+
80+
func autorollbackDisable(argv []string, cmdr cmd.Commander) error {
81+
usage := `
82+
Disables autorollback for an app.
83+
84+
Usage: drycc autorollback:disable [options]
85+
86+
Options:
87+
-a --app=<app>
88+
the uniquely identifiable name of the application.
89+
`
90+
91+
args, err := docopt.ParseArgs(usage, argv, "")
92+
93+
if err != nil {
94+
return err
95+
}
96+
97+
return cmdr.AutorollbackDisable(safeGetString(args, "--app"))
98+
}

0 commit comments

Comments
 (0)