Commit Diff


commit - e6fcfaf5b395db10ed791a73814b9e002be4a980
commit + 191337d0c3d59aa9a990eb5192664d5c5079f187
blob - /dev/null
blob + f81739c5afa8cc400c9e3e2556618fa8566ff45e (mode 644)
--- /dev/null
+++ checker.go
@@ -0,0 +1,83 @@
+package icinga
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"strings"
+)
+
+type checker interface {
+	object
+	Check(*Client) error
+}
+
+type StateType int
+
+const (
+	StateSoft StateType = 0 + iota
+	StateHard
+)
+
+func (st StateType) String() string {
+	switch st {
+	case StateSoft:
+		return "StateSoft"
+	case StateHard:
+		return "StateHard"
+	}
+	return "unsupported state type"
+}
+
+func (s Service) Check(c *Client) error {
+	return c.check(s)
+}
+
+func (h Host) Check(c *Client) error {
+	return c.check(h)
+}
+
+func splitServiceName(name string) []string {
+	return strings.SplitN(name, "!", 2)
+}
+
+func (c *Client) check(ch checker) error {
+	var filter struct {
+		Type string `json:"type"`
+		Expr string `json:"filter"`
+	}
+	switch v := ch.(type) {
+	case Host:
+		filter.Type = "Host"
+		filter.Expr = fmt.Sprintf("host.name == %q", v.Name)
+	case Service:
+		filter.Type = "Service"
+		a := splitServiceName(v.Name)
+		if len(a) != 2 {
+			return fmt.Errorf("check %s: invalid service name", v.Name)
+		}
+		host := a[0]
+		service := a[1]
+		filter.Expr = fmt.Sprintf("host.name == %q && service.name == %q", host, service)
+	default:
+		return fmt.Errorf("cannot check %T", v)
+	}
+
+	buf := &bytes.Buffer{}
+	if err := json.NewEncoder(buf).Encode(filter); err != nil {
+		return err
+	}
+	resp, err := c.post("/actions/reschedule-check", buf)
+	if err != nil {
+		return fmt.Errorf("check %s: %w", ch.name(), err)
+	}
+	switch resp.StatusCode {
+	case http.StatusOK:
+		return nil
+	case http.StatusNotFound:
+		return fmt.Errorf("check %s: %w", ch.name(), ErrNotExist)
+	default:
+		return fmt.Errorf("check %s: %s", ch.name(), resp.Status)
+	}
+}
blob - cfb416dc03d1d61daf3291217af43e419123563b (mode 644)
blob + /dev/null
--- host_test.go
+++ /dev/null
@@ -1,83 +0,0 @@
-package icinga
-
-import (
-	"errors"
-	"math/rand"
-	"sort"
-	"testing"
-)
-
-func randomHostname() string {
-	var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
-	b := make([]rune, 8)
-	for i := range b {
-		b[i] = letters[rand.Intn(len(letters))]
-	}
-	return string(b) + ".example.org"
-}
-
-func compareStringSlice(a, b []string) bool {
-	if len(a) != len(b) {
-		return false
-	}
-	for i, v := range a {
-		if v != b[i] {
-			return false
-		}
-	}
-	return true
-}
-
-func TestFilter(t *testing.T) {
-	client, err := newTestClient()
-	if err != nil {
-		t.Skipf("no local test icinga? got: %v", err)
-	}
-
-	hostgroup := HostGroup{Name: "examples", DisplayName: "Test Group"}
-	if err := client.CreateHostGroup(hostgroup); err != nil {
-		t.Error(err)
-	}
-	hostgroup, err = client.LookupHostGroup(hostgroup.Name)
-	if err != nil {
-		t.Error(err)
-	}
-	defer client.DeleteHostGroup(hostgroup.Name)
-
-	var want, got []string
-	for i := 0; i < 5; i++ {
-		h := Host{
-			Name:         randomHostname(),
-			CheckCommand: "hostalive",
-			Groups:       []string{hostgroup.Name},
-		}
-		want = append(want, h.Name)
-		if err := client.CreateHost(h); err != nil {
-			if !errors.Is(err, ErrExist) {
-				t.Error(err)
-			}
-			continue
-		}
-		t.Logf("created host %s", h.Name)
-	}
-	defer func() {
-		for _, name := range want {
-			if err := client.DeleteHost(name); err != nil {
-				t.Log(err)
-			}
-		}
-	}()
-	hosts, err := client.Hosts("match(\"*example.org\", host.name)")
-	if err != nil {
-		t.Fatal(err)
-	}
-	for _, h := range hosts {
-		got = append(got, h.Name)
-	}
-	sort.Strings(want)
-	sort.Strings(got)
-	if !compareStringSlice(want, got) {
-		t.Fail()
-	}
-	t.Logf("want %+v got %+v", want, got)
-}
blob - /dev/null
blob + d6de04aa780b601ace52aa53f0fdb4d82850dcdd (mode 644)
--- /dev/null
+++ icinga_test.go
@@ -0,0 +1,136 @@
+package icinga_test
+
+import (
+	"crypto/tls"
+	"errors"
+	"math/rand"
+	"net/http"
+	"reflect"
+	"sort"
+	"testing"
+
+	"olowe.co/icinga"
+)
+
+func randomHostname() string {
+	var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
+	b := make([]rune, 8)
+	for i := range b {
+		b[i] = letters[rand.Intn(len(letters))]
+	}
+	return string(b) + ".example.org"
+}
+
+func newTestClient() (*icinga.Client, error) {
+	tp := http.DefaultTransport.(*http.Transport)
+	tp.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
+	c := http.DefaultClient
+	c.Transport = tp
+	return icinga.Dial("127.0.0.1:5665", "root", "icinga", c)
+}
+
+func compareStringSlice(a, b []string) bool {
+	if len(a) != len(b) {
+		return false
+	}
+	for i, v := range a {
+		if v != b[i] {
+			return false
+		}
+	}
+	return true
+}
+
+func TestFilter(t *testing.T) {
+	client, err := newTestClient()
+	if err != nil {
+		t.Skipf("no local test icinga? got: %v", err)
+	}
+
+	hostgroup := icinga.HostGroup{Name: "examples", DisplayName: "Test Group"}
+	if err := client.CreateHostGroup(hostgroup); err != nil {
+		t.Error(err)
+	}
+	hostgroup, err = client.LookupHostGroup(hostgroup.Name)
+	if err != nil {
+		t.Error(err)
+	}
+	defer client.DeleteHostGroup(hostgroup.Name)
+
+	var want, got []string
+	for i := 0; i < 5; i++ {
+		h := icinga.Host{
+			Name:         randomHostname(),
+			CheckCommand: "hostalive",
+			Groups:       []string{hostgroup.Name},
+		}
+		want = append(want, h.Name)
+		if err := client.CreateHost(h); err != nil {
+			if !errors.Is(err, icinga.ErrExist) {
+				t.Error(err)
+			}
+			continue
+		}
+		t.Logf("created host %s", h.Name)
+	}
+	defer func() {
+		for _, name := range want {
+			if err := client.DeleteHost(name); err != nil {
+				t.Log(err)
+			}
+		}
+	}()
+	hosts, err := client.Hosts("match(\"*example.org\", host.name)")
+	if err != nil {
+		t.Fatal(err)
+	}
+	for _, h := range hosts {
+		got = append(got, h.Name)
+	}
+	sort.Strings(want)
+	sort.Strings(got)
+	if !compareStringSlice(want, got) {
+		t.Fail()
+	}
+	t.Logf("want %+v got %+v", want, got)
+}
+
+func TestUserRoundTrip(t *testing.T) {
+	client, err := newTestClient()
+	if err != nil {
+		t.Skipf("no local test icinga? got: %v", err)
+	}
+	want := icinga.User{Name: "olly", Email: "olly@example.com", Groups: []string{}}
+	if err := client.CreateUser(want); err != nil && !errors.Is(err, icinga.ErrExist) {
+		t.Fatal(err)
+	}
+	defer func() {
+		if err := client.DeleteUser(want.Name); err != nil {
+			t.Error(err)
+		}
+	}()
+	got, err := client.LookupUser(want.Name)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !reflect.DeepEqual(want, got) {
+		t.Errorf("want %+v, got %+v", want, got)
+	}
+}
+
+func TestChecker(t *testing.T) {
+	client, err := newTestClient()
+	if err != nil {
+		t.Skipf("no local test icinga? got: %v", err)
+	}
+
+	s := icinga.Service{Name: "9p.io!http"}
+	if err := s.Check(client); err != nil {
+		t.Fatal(err)
+	}
+	s, err = client.LookupService("9p.io!http")
+	if err != nil {
+		t.Fatal(err)
+	}
+	t.Logf("%+v\n", s)
+}
blob - f6c54ed27fec491ddd88b23d317b3dab0177b880
blob + 8accc7e71cba819abb61b5a00fc62fd80432b8b1
--- user_test.go
+++ user_test.go
@@ -1,23 +1,12 @@
 package icinga
 
 import (
-	"crypto/tls"
 	"encoding/json"
-	"errors"
-	"net/http"
 	"os"
 	"reflect"
 	"testing"
 )
 
-func newTestClient() (*Client, error) {
-	tp := http.DefaultTransport.(*http.Transport)
-	tp.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
-	c := http.DefaultClient
-	c.Transport = tp
-	return Dial("127.0.0.1:5665", "root", "icinga", c)
-}
-
 func TestUser(t *testing.T) {
 	want := User{Name: "test", Email: "test@example.com", Groups: []string{}}
 	f, err := os.Open("testdata/users.json")
@@ -54,26 +43,3 @@ func TestUserMarshal(t *testing.T) {
 	}
 	t.Logf("want %s, got %s", want, got)
 }
-
-func TestUserRoundTrip(t *testing.T) {
-	client, err := newTestClient()
-	if err != nil {
-		t.Skipf("no local test icinga? got: %v", err)
-	}
-	want := User{Name: "olly", Email: "olly@example.com", Groups: []string{}}
-	if err := client.CreateUser(want); err != nil && !errors.Is(err, ErrExist) {
-		t.Fatal(err)
-	}
-	defer func() {
-		if err := client.DeleteUser(want.Name); err != nil {
-			t.Error(err)
-		}
-	}()
-	got, err := client.LookupUser(want.Name)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !reflect.DeepEqual(want, got) {
-		t.Errorf("want %+v, got %+v", want, got)
-	}
-}