commit 2c4d16aea2e6138d88d6ecb7cec9d9af2e793593 from: Oliver Lowe date: Thu Dec 23 23:42:03 2021 UTC initial commit commit - /dev/null commit + 2c4d16aea2e6138d88d6ecb7cec9d9af2e793593 blob - /dev/null blob + 74e15e763ea7ca51a6c62e3d0d4b49f9d7ede835 (mode 644) --- /dev/null +++ README.md @@ -0,0 +1,20 @@ +Icinga2 servers in the wild often serve self-signed certificates which +fail verification by Go's tls client. To ignore the errors, Dial the server +with a modified http.Client: + + c := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + }, + } + client, err := icinga.Dial(host, user, pass, c) + if err != nil { + // handle error + } + ... + +## Why? + +The terraform provider... blob - /dev/null blob + 8dbad63c2e9dad8498eae11cb3ce6bb942cdff2a (mode 644) --- /dev/null +++ go.mod @@ -0,0 +1,3 @@ +module olowe.co/icinga + +go 1.17 blob - /dev/null blob + 0511d96326f694a7814290a8265fd08cf036609c (mode 644) --- /dev/null +++ http.go @@ -0,0 +1,71 @@ +package icinga + +import ( + "encoding/json" + "io" + "net/http" +) + +const versionPrefix = "/v1" + +func newRequest(method, host, path string, body io.Reader) (*http.Request, error) { + url := "https://" + host + versionPrefix + path + req, err := http.NewRequest(method, url, body) + if err != nil { + return nil, err + } + switch req.Method { + case http.MethodPost, http.MethodPut: + req.Header.Set("Content-Type", "application/json") + } + return req, nil +} + +func (c *Client) get(path string) (*http.Response, error) { + req, err := newRequest(http.MethodGet, c.host, path, nil) + if err != nil { + return nil, err + } + return c.do(req) +} + +func (c *Client) post(path string, body io.Reader) (*http.Response, error) { + req, err := newRequest(http.MethodPost, c.host, path, body) + if err != nil { + return nil, err + } + return c.do(req) +} + + +func (c *Client) put(path string, body io.Reader) (*http.Response, error) { + req, err := newRequest(http.MethodPut, c.host, path, body) + if err != nil { + return nil, err + } + return c.do(req) +} + +func (c *Client) delete(path string, body io.Reader) (*http.Response, error) { + req, err := newRequest(http.MethodDelete, c.host, path, nil) + if err != nil { + return nil, err + } + return c.do(req) +} + +func (c *Client) do(req *http.Request) (*http.Response, error) { + req.SetBasicAuth(c.username, c.password) + return c.httpClient.Do(req) +} + +// TODO +type Result struct{} +func results(resp *http.Response) (Result, error) { + defer resp.Body.Close() + var results []Result + if err := json.NewDecoder(resp.Body).Decode(&results); err != nil { + return Result{}, err + } + return Result{}, nil +} blob - /dev/null blob + 3b34af55df20ec80e209f19ad2f68158bb973e24 (mode 644) --- /dev/null +++ icinga.go @@ -0,0 +1,32 @@ +package icinga + +import ( + "fmt" + "net/http" +) + +type Client struct { + host string + username string + password string + httpClient *http.Client +} + +func Dial(host, username, password string, client *http.Client) (*Client, error) { + c := &Client{host, username, password, client} + if _, err := c.Status(); err != nil { + return nil, err + } + return c, nil +} + +func (c *Client) Status() (*http.Response, error) { + resp, err := c.get("/status") + if err != nil { + return nil, err + } + if resp.StatusCode != http.StatusOK { + return resp, fmt.Errorf("status %s", resp.Status) + } + return resp, nil +} blob - /dev/null blob + 0afa410559a68ae012d13520f47e74a6b29fa0d9 (mode 644) --- /dev/null +++ users.go @@ -0,0 +1,51 @@ +package icinga + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" +) + +type User struct { + Name string + Type string + Attrs struct { + Email string + } +} + +var testUser = User{ + Name: "Olly", + Type: "User", + Attrs: struct { + Email string + }{Email: "olly@example.com"}, +} + +func (c *Client) Users() ([]User, error) { + resp, err := c.get("/objects/users") + if err != nil { + return nil, err + } + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("get /objects/users: status %s", resp.Status) + } + return []User{testUser}, nil +} + +func (c *Client) CreateUser(name, email string) error { + u := User{ + Name: name, + Type: "User", + Attrs: struct { + Email string + }{email}, + } + buf := &bytes.Buffer{} + if err := json.NewEncoder(buf).Encode(u); err != nil { + return err + } + _, err := c.put("/objects/users/"+name, buf) + return err +}