Skip to content

Commit 37cdb52

Browse files
committed
feat(healthcheck): Add support for healthcheck per proctype
1 parent 51a2103 commit 37cdb52

5 files changed

Lines changed: 101 additions & 32 deletions

File tree

cmd/healthchecks.go

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,33 @@
11
package cmd
22

33
import (
4+
"errors"
45
"fmt"
6+
"io"
7+
"os"
58

69
"github.com/deis/controller-sdk-go/api"
710
"github.com/deis/controller-sdk-go/config"
811
)
912

13+
func printHealthCheck(out io.Writer, healthcheck api.Healthchecks) {
14+
fmt.Fprintln(out, "--- Liveness")
15+
if livenessProbe, found := healthcheck["livenessProbe"]; found {
16+
fmt.Fprintln(out, livenessProbe)
17+
} else {
18+
fmt.Fprintln(out, "No liveness probe configured.")
19+
}
20+
21+
fmt.Fprintln(out, "\n--- Readiness")
22+
if readinessProbe, found := healthcheck["readinessProbe"]; found {
23+
fmt.Fprintln(out, readinessProbe)
24+
} else {
25+
fmt.Fprintln(out, "No readiness probe configured.")
26+
}
27+
}
28+
1029
// HealthchecksList lists an app's healthchecks.
11-
func HealthchecksList(appID string) error {
30+
func HealthchecksList(appID, procType string) error {
1231
s, appID, err := load(appID)
1332

1433
if err != nil {
@@ -22,25 +41,25 @@ func HealthchecksList(appID string) error {
2241
}
2342

2443
fmt.Printf("=== %s Healthchecks\n\n", appID)
25-
26-
fmt.Println("--- Liveness")
27-
if livenessProbe, found := config.Healthcheck["livenessProbe"]; found {
28-
fmt.Println(livenessProbe)
44+
if procType == "" {
45+
for proc, healthcheck := range config.Healthcheck {
46+
fmt.Println(proc + ":")
47+
printHealthCheck(os.Stdout, *healthcheck)
48+
}
2949
} else {
30-
fmt.Println("No liveness probe configured.")
50+
fmt.Println(procType + ":")
51+
if healthcheck, found := config.Healthcheck[procType]; found {
52+
printHealthCheck(os.Stdout, *healthcheck)
53+
} else {
54+
return errors.New(appID + " doesn't have proctype" + procType)
55+
}
3156
}
3257

33-
fmt.Println("\n--- Readiness")
34-
if readinessProbe, found := config.Healthcheck["readinessProbe"]; found {
35-
fmt.Println(readinessProbe)
36-
} else {
37-
fmt.Println("No readiness probe configured.")
38-
}
3958
return nil
4059
}
4160

4261
// HealthchecksSet sets an app's healthchecks.
43-
func HealthchecksSet(appID, healthcheckType string, probe *api.Healthcheck) error {
62+
func HealthchecksSet(appID, healthcheckType, procType string, probe *api.Healthcheck) error {
4463
s, appID, err := load(appID)
4564

4665
if err != nil {
@@ -50,10 +69,11 @@ func HealthchecksSet(appID, healthcheckType string, probe *api.Healthcheck) erro
5069
fmt.Printf("Applying %s healthcheck... ", healthcheckType)
5170

5271
quit := progress()
53-
configObj := api.Config{}
54-
configObj.Healthcheck = make(map[string]*api.Healthcheck)
5572

56-
configObj.Healthcheck[healthcheckType] = probe
73+
healthcheckMap := make(api.Healthchecks)
74+
healthcheckMap[healthcheckType] = probe
75+
configObj := api.Config{Healthcheck: make(map[string]*api.Healthchecks)}
76+
configObj.Healthcheck[procType] = &healthcheckMap
5777

5878
_, err = config.Set(s.Client, appID, configObj)
5979

@@ -66,11 +86,11 @@ func HealthchecksSet(appID, healthcheckType string, probe *api.Healthcheck) erro
6686

6787
fmt.Print("done\n\n")
6888

69-
return HealthchecksList(appID)
89+
return HealthchecksList(appID, procType)
7090
}
7191

7292
// HealthchecksUnset removes an app's healthchecks.
73-
func HealthchecksUnset(appID string, healthchecks []string) error {
93+
func HealthchecksUnset(appID, procType string, healthchecks []string) error {
7494
s, appID, err := load(appID)
7595

7696
if err != nil {
@@ -83,13 +103,15 @@ func HealthchecksUnset(appID string, healthchecks []string) error {
83103

84104
configObj := api.Config{}
85105

86-
healthcheckMap := make(map[string]*api.Healthcheck)
106+
healthchecksMap := make(map[string]*api.Healthchecks)
107+
healthcheckMap := make(api.Healthchecks)
87108

88109
for _, healthcheck := range healthchecks {
89110
healthcheckMap[healthcheck] = nil
90111
}
112+
healthchecksMap[procType] = &healthcheckMap
91113

92-
configObj.Healthcheck = healthcheckMap
114+
configObj.Healthcheck = healthchecksMap
93115

94116
_, err = config.Set(s.Client, appID, configObj)
95117

@@ -102,5 +124,5 @@ func HealthchecksUnset(appID string, healthchecks []string) error {
102124

103125
fmt.Print("done\n\n")
104126

105-
return HealthchecksList(appID)
127+
return HealthchecksList(appID, procType)
106128
}

cmd/healthchecks_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package cmd
2+
3+
import (
4+
"bytes"
5+
"testing"
6+
7+
"github.com/arschles/assert"
8+
"github.com/deis/controller-sdk-go/api"
9+
)
10+
11+
func TestPrintHealthCheck(t *testing.T) {
12+
var b bytes.Buffer
13+
testHealthCheck := api.Healthchecks{}
14+
printHealthCheck(&b, testHealthCheck)
15+
assert.Equal(t, b.String(), "--- Liveness\nNo liveness probe configured.\n\n--- Readiness\nNo readiness probe configured.\n", "healthcheck")
16+
b.Reset()
17+
testHealthCheck["livenessProbe"] = &api.Healthcheck{}
18+
testHealthCheck["readinessProbe"] = &api.Healthcheck{}
19+
printHealthCheck(&b, testHealthCheck)
20+
assert.Equal(t, b.String(), "--- Liveness\nInitial Delay (seconds): 0\nTimeout (seconds): 0\nPeriod (seconds): 0\nSuccess Threshold: 0\nFailure Threshold: 0\nExec Probe: N/A\nHTTP GET Probe: N/A\nTCP Socket Probe: N/A\n\n--- Readiness\nInitial Delay (seconds): 0\nTimeout (seconds): 0\nPeriod (seconds): 0\nSuccess Threshold: 0\nFailure Threshold: 0\nExec Probe: N/A\nHTTP GET Probe: N/A\nTCP Socket Probe: N/A\n", "healthcheck")
21+
}

glide.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

glide.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ import:
1616
- package: github.com/olekukonko/tablewriter
1717
- package: github.com/arschles/assert
1818
- package: github.com/deis/controller-sdk-go
19-
version: cd0f563b127736127e0e9debeddcbcb014621b04
19+
version: b5c341604961fcf0ec326ca403b720e1aa6ff527

parser/healthchecks.go

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ import (
1111
docopt "github.com/docopt/docopt-go"
1212
)
1313

14+
// TODO: This is for supporting backward compatibility and should be removed
15+
// in future when next major version will be released.
16+
const (
17+
defaultProcType string = "web/cmd"
18+
)
19+
1420
// Healthchecks routes ealthcheck commands to their specific function
1521
func Healthchecks(argv []string) error {
1622
usage := `
@@ -54,6 +60,8 @@ Usage: deis healthchecks:list [options]
5460
Options:
5561
-a --app=<app>
5662
the uniquely identifiable name of the application.
63+
--type=<type>
64+
the procType for which the health check needs to be listed.
5765
`
5866

5967
args, err := docopt.Parse(usage, argv, true, "", false, true)
@@ -62,7 +70,13 @@ Options:
6270
return err
6371
}
6472

65-
return cmd.HealthchecksList(safeGetValue(args, "--app"))
73+
app := safeGetValue(args, "--app")
74+
procType := safeGetValue(args, "--type")
75+
if procType == "" {
76+
procType = defaultProcType
77+
}
78+
79+
return cmd.HealthchecksList(app, procType)
6680
}
6781

6882
func healthchecksSet(argv []string) error {
@@ -111,6 +125,8 @@ Options:
111125
the uniquely identifiable name for the application.
112126
-p --path=<path>
113127
the relative URL path for 'httpGet' probes. [default: /]
128+
--type=<type>
129+
the procType for which the health check needs to be applied.
114130
--header=<header>...
115131
the HTTP headers to send for 'httpGet' probes, separated by commas.
116132
--initial-delay-timeout=<initial-delay-timeout>
@@ -133,6 +149,7 @@ Options:
133149

134150
app := safeGetValue(args, "--app")
135151
path := safeGetValue(args, "--path")
152+
procType := safeGetValue(args, "--type")
136153
initialDelayTimeout := safeGetInt(args, "--initial-delay-timeout")
137154
timeoutSeconds := safeGetInt(args, "--timeout-seconds")
138155
periodSeconds := safeGetInt(args, "--period-seconds")
@@ -142,6 +159,9 @@ Options:
142159
if args["--headers"] != nil {
143160
headers = args["--headers"].([]string)
144161
}
162+
if procType == "" {
163+
procType = defaultProcType
164+
}
145165

146166
healthcheckType := args["<health-type>"].(string)
147167
probeType := args["<probe-type>"].(string)
@@ -193,22 +213,24 @@ Options:
193213
default:
194214
return fmt.Errorf("Invalid probe type. Must be one of: \"httpGet\", \"exec\"")
195215
}
196-
return cmd.HealthchecksSet(app, healthcheckType, probe)
216+
return cmd.HealthchecksSet(app, healthcheckType, procType, probe)
197217
}
198218

199219
func healthchecksUnset(argv []string) error {
200220
usage := `
201221
Unsets healthchecks for an application.
202222
203-
Usage: deis healthchecks:unset [options] <type>...
223+
Usage: deis healthchecks:unset [options] <health-type>...
204224
205225
Arguments:
206-
<type>
226+
<health-type>
207227
the healthcheck type, such as 'liveness' or 'readiness'.
208228
209229
Options:
210230
-a --app=<app>
211231
the uniquely identifiable name for the application.
232+
--type=<type>
233+
the procType for which the health check needs to be removed.
212234
`
213235

214236
args, err := docopt.Parse(usage, argv, true, "", false, true)
@@ -218,15 +240,19 @@ Options:
218240
}
219241

220242
app := safeGetValue(args, "--app")
221-
healthchecks := args["<type>"].([]string)
243+
healthchecks := args["<health-type>"].([]string)
244+
procType := safeGetValue(args, "--type")
245+
if procType == "" {
246+
procType = defaultProcType
247+
}
222248

223249
// NOTE(bacongobbler): k8s healthchecks use the term "livenessProbe" and "readinessProbe", so let's
224250
// add that to the end of the healthcheck type so the controller sees the right probe type
225251
for healthcheck := range healthchecks {
226252
healthchecks[healthcheck] += "Probe"
227253
}
228254

229-
return cmd.HealthchecksUnset(app, healthchecks)
255+
return cmd.HealthchecksUnset(app, procType, healthchecks)
230256
}
231257

232258
func parseHeaders(headers []string) ([]*api.KVPair, error) {

0 commit comments

Comments
 (0)