forked from cloudfoundry/bosh-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
problems.go
118 lines (89 loc) · 2.77 KB
/
problems.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package director
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
bosherr "github.com/cloudfoundry/bosh-utils/errors"
)
type Problem struct {
ID int // e.g. 4
Type string // e.g. "unresponsive_agent"
Description string // e.g. "api/1 (5efd2cb8-d73b-4e45-6df4-58f5dd5ec2ec) is not responding"
Data interface{}
Resolutions []ProblemResolution
}
var ProblemResolutionDefault ProblemResolution = ProblemResolution{
Name: "apply default resolution",
}
type ProblemResolution struct {
Name string `json:"name"` // e.g. "Skip for now", "Recreate VM"
Plan string `json:"plan"` // e.g. "ignore", "reboot_vm"
}
type ProblemAnswer struct {
ProblemID int
Resolution ProblemResolution
}
func (d DeploymentImpl) ScanForProblems() ([]Problem, error) {
err := d.client.ScanForProblems(d.name)
if err != nil {
return nil, err
}
return d.client.ListProblems(d.name)
}
func (d DeploymentImpl) ResolveProblems(answers []ProblemAnswer) error {
return d.client.ResolveProblems(d.name, answers)
}
func (c Client) ScanForProblems(deploymentName string) error {
if len(deploymentName) == 0 {
return bosherr.Error("Expected non-empty deployment name")
}
path := fmt.Sprintf("/deployments/%s/scans", deploymentName)
setHeaders := func(req *http.Request) {
req.Header.Add("Content-Type", "application/json")
}
_, err := c.taskClientRequest.PostResult(path, nil, setHeaders)
if err != nil {
return bosherr.WrapErrorf(
err, "Performing a scan on deployment '%s'", deploymentName)
}
return nil
}
func (c Client) ListProblems(deploymentName string) ([]Problem, error) {
var probs []Problem
if len(deploymentName) == 0 {
return probs, bosherr.Error("Expected non-empty deployment name")
}
path := fmt.Sprintf("/deployments/%s/problems", deploymentName)
err := c.clientRequest.Get(path, &probs)
if err != nil {
return probs, bosherr.WrapErrorf(
err, "Listing problems for deployment '%s'", deploymentName)
}
return probs, nil
}
func (c Client) ResolveProblems(deploymentName string, answers []ProblemAnswer) error {
if len(deploymentName) == 0 {
return bosherr.Error("Expected non-empty deployment name")
}
path := fmt.Sprintf("/deployments/%s/problems", deploymentName)
body := map[string]map[string]string{
"resolutions": map[string]string{},
}
for _, ans := range answers {
body["resolutions"][strconv.Itoa(ans.ProblemID)] = ans.Resolution.Name
}
reqBody, err := json.Marshal(body)
if err != nil {
return bosherr.WrapErrorf(err, "Marshaling request body")
}
setHeaders := func(req *http.Request) {
req.Header.Add("Content-Type", "application/json")
}
_, err = c.taskClientRequest.PutResult(path, reqBody, setHeaders)
if err != nil {
return bosherr.WrapErrorf(
err, "Resolving problems for deployment '%s'", deploymentName)
}
return nil
}