commit cb9dde9996675a4d56608eab8b57109da8484c29 from: Oliver Lowe date: Tue Jan 18 14:12:18 2022 UTC Let users schedule their own checks commit - dd1562c064ef82c610805dfd8cdaca5af54f6d22 commit + cb9dde9996675a4d56608eab8b57109da8484c29 blob - bb803fd93dae42f336a709dbcffefd36df670a84 blob + b9feba78821be80819231914337efeb72971926a --- checker.go +++ checker.go @@ -13,6 +13,11 @@ type checker interface { Check(*Client) error } +type checkFilter struct { + Type string `json:"type"` + Expr string `json:"filter"` +} + type StateType int const ( @@ -51,50 +56,71 @@ func splitServiceName(name string) []string { } 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) + return c.CheckHosts(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) + return c.CheckServices(fmt.Sprintf("host.name == %q && service.name == %q", host, service)) case HostGroup: - filter.Type = "Host" - filter.Expr = fmt.Sprintf("%q in host.groups", v.Name) + return c.CheckHosts(fmt.Sprintf("%q in host.groups", v.Name)) default: return fmt.Errorf("cannot check %T", v) } +} +// CheckHosts schedules checks for all services matching the filter expression +// filter. If no services match the filter, error wraps ErrNoMatch. +func (c *Client) CheckServices(filter string) error { + f := checkFilter{ + Type: "Service", + Expr: filter, + } + if err := scheduleCheck(c, f); err != nil { + return fmt.Errorf("check services %q: %w", filter, err) + } + return nil +} + +// CheckHosts schedules checks for all hosts matching the filter expression +// filter. If no hosts match the filter, error wraps ErrNoMatch. +func (c *Client) CheckHosts(filter string) error { + f := checkFilter{ + Type: "Host", + Expr: filter, + } + if err := scheduleCheck(c, f); err != nil { + return fmt.Errorf("check hosts %q: %w", filter, err) + } + return nil +} + +func scheduleCheck(c *Client, filter checkFilter) error { 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) + return err } if resp.StatusCode == http.StatusOK { return nil } else if resp.StatusCode == http.StatusNotFound { - return fmt.Errorf("check %s: %w", ch.name(), ErrNotExist) + return ErrNoMatch } defer resp.Body.Close() iresp, err := parseResponse(resp.Body) if err != nil { - return fmt.Errorf("check %s: parse response: %v", ch.name(), err) + return fmt.Errorf("parse response: %v", err) } if iresp.Error != nil { - return fmt.Errorf("check %s: %v", ch.name(), iresp.Error) + return iresp.Error } - return fmt.Errorf("check %s: %s", ch.name(), resp.Status) + return fmt.Errorf("%s", resp.Status) }