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