commit 6e415953de07ac11e0f54ac397d156b23f384a15
parent 9ab732cda40be5693e3f1ddba1a5ebf7de9e1bd5
Author: Oliver Lowe <o@olowe.co>
Date: Thu, 6 Jan 2022 12:30:37 +1100
dump
Diffstat:
| A | host.go | | | 34 | ++++++++++++++++++++++++++++++++++ |
| M | http.go | | | 46 | ++++++++++++++++++++++++++++++++++++++++++++-- |
| A | user.go | | | 75 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| D | users.go | | | 51 | --------------------------------------------------- |
4 files changed, 153 insertions(+), 53 deletions(-)
diff --git a/host.go b/host.go
@@ -0,0 +1,34 @@
+package icinga
+
+type Host struct {
+ Name string
+ State int
+}
+
+var ErrNoHost = errors.New("no such host")
+
+func (c *Client) Hosts() ([]Host, error) {
+ _, err := c.get("/objects/hosts")
+ if err != nil {
+ return nil, err
+ }
+ return nil, err
+}
+
+func (c *Client) LookupHost(name string) (Host, error) {
+ resp, err := c.get("/objects/hosts/" + name)
+ if err != nil {
+ return Host{}, err
+ }
+ if resp.StatusCode == http.StatusNotFound {
+ return Host{}, fmt.Errorf("lookup %s: %w", name, ErrNoHost)
+ }
+ return Host{}, err
+}
+
+func (c *Client) DeleteHost(name string) error {
+ if err := c.delete("/objects/hosts/" + name); err != nil {
+ return fmt.Errorf("delete host %s: %w", name, err)
+ }
+ return nil
+}
diff --git a/http.go b/http.go
@@ -1,12 +1,40 @@
package icinga
import (
+ "fmt"
"io"
"net/http"
+ "strings"
)
const versionPrefix = "/v1"
+type results struct {
+ Results []result
+}
+
+type result struct {
+ Attrs interface{}
+ Code int
+ Errors []string
+ Name string
+ Type string
+}
+
+var ErrNoObject = errors.New("no such object")
+
+func (res results) Error() string {
+ var s []string
+ for _, r := range res.Results {
+ s = append(s, r.Error())
+ }
+ return strings.Join(s, ", ")
+}
+
+func (r result) Error() string {
+ return strings.Join(r.Errors, ", ")
+}
+
func newRequest(method, host, path string, body io.Reader) (*http.Request, error) {
url := "https://" + host + versionPrefix + path
req, err := http.NewRequest(method, url, body)
@@ -51,12 +79,26 @@ func (c *Client) put(path string, body io.Reader) (*http.Response, error) {
return c.do(req)
}
-func (c *Client) delete(path string, body io.Reader) (*http.Response, error) {
+func (c *Client) delete(path string) error {
req, err := newRequest(http.MethodDelete, c.host, path, nil)
if err != nil {
return nil, err
}
- return c.do(req)
+ resp, err := c.do(req)
+ if err != nil {
+ return err
+ }
+ if resp.StatusCode == http.StatusOK {
+ return nil
+ } else if resp.StatusCode == http.StatusNotFound {
+ return ErrNoObject
+ }
+ defer resp.Body.Close()
+ var results results
+ if err := json.NewDecoder(resp.Body).Decode(&results); err != nil {
+ return fmt.Errorf("decode response: %w", err)
+ }
+ return results
}
func (c *Client) do(req *http.Request) (*http.Response, error) {
diff --git a/user.go b/user.go
@@ -0,0 +1,75 @@
+package icinga
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "net/http"
+)
+
+type User struct {
+ Name string
+ Email string
+ Groups []string
+}
+
+var testUser = User{
+ Name: "testUser",
+ Email: "test@example.com",
+}
+
+var ErrNoUser = errors.New("no such user")
+
+func (u User) MarshalJSON() ([]byte, error) {
+ type Alias User
+ return json.Marshal(&struct {
+ Attrs Alias
+ }{Attrs: (Alias)(u)})
+}
+
+func (c *Client) Users() ([]User, error) {
+ _, err := c.get("/objects/users")
+ if err != nil {
+ return nil, err
+ }
+ return []User{testUser}, nil
+}
+
+func (c *Client) LookupUser(name string) (User, error) {
+ resp, err := c.get("/objects/users/" + name)
+ if err != nil {
+ return User{}, err
+ }
+ if resp.StatusCode == http.StatusNotFound {
+ return User{}, fmt.Errorf("lookup %s: %w", name, ErrNoUser)
+ }
+ return testUser, nil
+}
+
+func (c *Client) CreateUser(u User) error {
+ buf := &bytes.Buffer{}
+ if err := json.NewEncoder(buf).Encode(u); err != nil {
+ return err
+ }
+ resp, err := c.put("/objects/users/"+u.Name, buf)
+ if err != nil {
+ return fmt.Errorf("create %s: %w", u.Name, err)
+ }
+ if resp.StatusCode == http.StatusOK {
+ return nil
+ }
+ defer resp.Body.Close()
+ var results results
+ if err := json.NewDecoder(resp.Body).Decode(&results); err != nil {
+ return fmt.Errorf("create %s: decode response: %w", u.Name, err)
+ }
+ return fmt.Errorf("create %s: %w", u.Name, results)
+}
+
+func (c *Client) DeleteUser(name string) error {
+ if err := c.delete("/objects/users/" + name); err != nil {
+ return fmt.Errorf("delete user %s: %w", name, err)
+ }
+ return nil
+}
diff --git a/users.go b/users.go
@@ -1,51 +0,0 @@
-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
-}