Blame


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