Blob


1 package icinga
3 import (
4 "fmt"
5 "io"
6 "net/http"
7 "net/url"
8 "strings"
9 )
11 const versionPrefix = "/v1"
13 // NewRequest returns an authenticated HTTP request with appropriate header
14 // for sending to an Icinga2 server.
15 func NewRequest(method, url, username, password string, body io.Reader) (*http.Request, error) {
16 req, err := http.NewRequest(method, url, body)
17 if err != nil {
18 return nil, err
19 }
20 switch req.Method {
21 case http.MethodGet, http.MethodDelete:
22 req.Header.Set("Accept", "application/json")
23 case http.MethodPost, http.MethodPut:
24 req.Header.Set("Accept", "application/json")
25 req.Header.Set("Content-Type", "application/json")
26 default:
27 return nil, fmt.Errorf("new request: unsupported method %s", req.Method)
28 }
29 req.SetBasicAuth(username, password)
30 return req, nil
31 }
33 // filterEncode url-encodes the filter expression expr in the required
34 // format to be included in a request. Notably, spaces need to be encoded
35 // as "%20", not "+" as returned by the url package.
36 func filterEncode(expr string) string {
37 v := url.Values{}
38 v.Set("filter", expr)
39 return strings.ReplaceAll(v.Encode(), "+", "%20")
40 }
42 func (c *Client) get(path, filter string) (*http.Response, error) {
43 u, err := url.Parse("https://" + c.addr + versionPrefix + path)
44 if err != nil {
45 return nil, err
46 }
47 if filter != "" {
48 u.RawQuery = filterEncode(filter)
49 }
50 req, err := NewRequest(http.MethodGet, u.String(), c.username, c.password, nil)
51 if err != nil {
52 return nil, err
53 }
54 return c.Do(req)
55 }
57 func (c *Client) post(path string, body io.Reader) (*http.Response, error) {
58 url := "https://" + c.addr + versionPrefix + path
59 req, err := NewRequest(http.MethodPost, url, c.username, c.password, body)
60 if err != nil {
61 return nil, err
62 }
63 return c.Do(req)
64 }
66 func (c *Client) put(path string, body io.Reader) (*http.Response, error) {
67 url := "https://" + c.addr + versionPrefix + path
68 req, err := NewRequest(http.MethodPut, url, c.username, c.password, body)
69 if err != nil {
70 return nil, err
71 }
72 return c.Do(req)
73 }
75 func (c *Client) delete(path string, cascade bool) (*http.Response, error) {
76 u, err := url.Parse("https://" + c.addr + versionPrefix + path)
77 if err != nil {
78 return nil, err
79 }
80 if cascade {
81 v := url.Values{}
82 v.Set("cascade", "1")
83 u.RawQuery = v.Encode()
84 }
85 req, err := NewRequest(http.MethodDelete, u.String(), c.username, c.password, nil)
86 if err != nil {
87 return nil, err
88 }
89 return c.Do(req)
90 }