Blob


1 package icinga
3 import (
4 "encoding/json"
5 "errors"
6 "fmt"
7 "io"
8 "strings"
9 )
11 type apiResponse struct {
12 Results []struct {
13 Name string
14 Type string
15 Errors []string
16 Permissions []string
17 Attrs json.RawMessage
18 }
19 Status string
20 }
22 type response struct {
23 Results []object
24 Error error
25 }
27 func parseResponse(r io.Reader) (*response, error) {
28 var apiresp apiResponse
29 if err := json.NewDecoder(r).Decode(&apiresp); err != nil {
30 return nil, err
31 }
32 // Confusingly the top-level status field in an API response contains
33 // an error message. Successful statuses are actually held in the
34 // status field in Results!
35 if apiresp.Status != "" {
36 return &response{Error: errors.New(apiresp.Status)}, nil
37 }
38 resp := &response{}
39 for _, r := range apiresp.Results {
40 if len(r.Errors) > 0 {
41 resp.Error = errors.New(strings.Join(r.Errors, ", "))
42 // got an error so nothing left in the API response
43 break
44 }
45 if r.Type == "" {
46 continue //
47 }
48 switch r.Type {
49 case "Host":
50 var h Host
51 h.Name = r.Name
52 if err := json.Unmarshal(r.Attrs, &h); err != nil {
53 return nil, err
54 }
55 resp.Results = append(resp.Results, h)
56 case "Service":
57 var s Service
58 s.Name = r.Name
59 if err := json.Unmarshal(r.Attrs, &s); err != nil {
60 return nil, err
61 }
62 resp.Results = append(resp.Results, s)
63 case "User":
64 var u User
65 u.Name = r.Name
66 if err := json.Unmarshal(r.Attrs, &u); err != nil {
67 return nil, err
68 }
69 resp.Results = append(resp.Results, u)
70 case "HostGroup":
71 var h HostGroup
72 h.Name = r.Name
73 if err := json.Unmarshal(r.Attrs, &h); err != nil {
74 return nil, err
75 }
76 resp.Results = append(resp.Results, h)
77 default:
78 return nil, fmt.Errorf("unsupported unmarshal of type %s", r.Type)
79 }
80 }
81 return resp, nil
82 }
84 func objectFromLookup(resp *response) (object, error) {
85 if len(resp.Results) == 0 {
86 return nil, errors.New("empty results")
87 } else if len(resp.Results) > 1 {
88 return nil, errors.New("too many results")
89 }
90 return resp.Results[0], nil
91 }