Blob


1 package icinga
3 import (
4 "bytes"
5 "encoding/json"
6 "errors"
7 "fmt"
8 "net/http"
9 "strings"
10 )
12 type object interface {
13 name() string
14 path() string
15 }
17 // jsonForCreate marshals obj into the required JSON object to be sent
18 // in the body of a PUT request to Icinga. Some fields of obj must not be set for
19 // Icinga to create the object. Since some of those fields are structs
20 // (and not pointers to structs), they are always included, even if unset.
21 // jsonForCreate overrides those fields to always be empty. Other fields are left
22 // alone to let Icinga report an error for us.
23 func jsonForCreate(obj object) ([]byte, error) {
24 m := make(map[string]interface{})
25 switch v := obj.(type) {
26 case User, HostGroup:
27 m["attrs"] = v
28 case Host:
29 aux := &struct {
30 LastCheck *struct{} `json:",omitempty"`
31 LastCheckResult *struct{} `json:"last_check_result,omitempty"`
32 Host
33 }{Host: v}
34 m["attrs"] = aux
35 case Service:
36 aux := &struct {
37 LastCheck *struct{} `json:",omitempty"`
38 LastCheckResult *struct{} `json:"last_check_result,omitempty"`
39 Service
40 }{Service: v}
41 m["attrs"] = aux
42 default:
43 return nil, fmt.Errorf("marshal %T for creation unsupported", v)
44 }
45 return json.Marshal(m)
46 }
48 //go:generate ./crud.sh -o crud.go
50 func (c *Client) lookupObject(objpath string) (object, error) {
51 resp, err := c.get(objpath, "")
52 if err != nil {
53 return nil, err
54 }
55 defer resp.Body.Close()
56 if resp.StatusCode == http.StatusNotFound {
57 return nil, ErrNotExist
58 }
59 iresp, err := parseResponse(resp.Body)
60 if err != nil {
61 return nil, fmt.Errorf("parse response: %v", err)
62 } else if iresp.Error != nil {
63 return nil, iresp.Error
64 } else if resp.StatusCode != http.StatusOK {
65 return nil, errors.New(resp.Status)
66 }
67 return objectFromLookup(iresp)
68 }
70 func (c *Client) filterObjects(objpath, expr string) ([]object, error) {
71 resp, err := c.get(objpath, expr)
72 if err != nil {
73 return nil, err
74 }
75 defer resp.Body.Close()
76 iresp, err := parseResponse(resp.Body)
77 if err != nil {
78 return nil, fmt.Errorf("parse response: %v", err)
79 } else if iresp.Error != nil {
80 return nil, iresp.Error
81 } else if resp.StatusCode != http.StatusOK {
82 return nil, errors.New(resp.Status)
83 } else if len(iresp.Results) == 0 {
84 return nil, ErrNoMatch
85 }
86 return iresp.Results, nil
87 }
89 func (c *Client) createObject(obj object) error {
90 b, err := jsonForCreate(obj)
91 if err != nil {
92 return fmt.Errorf("marshal into json: %v", err)
93 }
94 resp, err := c.put(obj.path(), bytes.NewReader(b))
95 if err != nil {
96 return err
97 }
98 if resp.StatusCode == http.StatusOK {
99 return nil
101 defer resp.Body.Close()
102 iresp, err := parseResponse(resp.Body)
103 if err != nil {
104 return fmt.Errorf("parse response: %v", err)
106 if strings.Contains(iresp.Error.Error(), "already exists") {
107 return ErrExist
109 return iresp.Error
112 func (c *Client) deleteObject(objpath string, cascade bool) error {
113 resp, err := c.delete(objpath, cascade)
114 if err != nil {
115 return err
117 defer resp.Body.Close()
118 if resp.StatusCode == http.StatusOK {
119 return nil
120 } else if resp.StatusCode == http.StatusNotFound {
121 return ErrNotExist
123 iresp, err := parseResponse(resp.Body)
124 if err != nil {
125 return fmt.Errorf("parse response: %v", err)
127 return iresp.Error