icinga

Icinga2 API client in Go
git clone https://git.olowe.co/icinga
Log | Files | Refs | README | LICENSE

object.go (3245B)


      1 package icinga
      2 
      3 import (
      4 	"bytes"
      5 	"encoding/json"
      6 	"errors"
      7 	"fmt"
      8 	"net/http"
      9 	"strings"
     10 )
     11 
     12 type object interface {
     13 	name() string
     14 	path() string
     15 }
     16 
     17 // jsonForCreate marshals obj into the required JSON object to be sent
     18 // in the body of a PUT request to Icinga. Some fields of obj must not be set for
     19 // Icinga to create the object. Since some of those fields are structs
     20 // (and not pointers to structs), they are always included, even if unset.
     21 // jsonForCreate overrides those fields to always be empty. Other fields are left
     22 // alone to let Icinga report an error for us.
     23 func jsonForCreate(obj object) ([]byte, error) {
     24 	m := make(map[string]interface{})
     25 	switch v := obj.(type) {
     26 	case User, HostGroup:
     27 		m["attrs"] = v
     28 	case Host:
     29 		aux := &struct {
     30 			LastCheck       *struct{} `json:",omitempty"`
     31 			LastCheckResult *struct{} `json:"last_check_result,omitempty"`
     32 			Host
     33 		}{Host: v}
     34 		m["attrs"] = aux
     35 	case Service:
     36 		aux := &struct {
     37 			LastCheck       *struct{} `json:",omitempty"`
     38 			LastCheckResult *struct{} `json:"last_check_result,omitempty"`
     39 			Service
     40 		}{Service: v}
     41 		m["attrs"] = aux
     42 	default:
     43 		return nil, fmt.Errorf("marshal %T for creation unsupported", v)
     44 	}
     45 	return json.Marshal(m)
     46 }
     47 
     48 //go:generate ./crud.sh -o crud.go
     49 
     50 func (c *Client) lookupObject(objpath string) (object, error) {
     51 	resp, err := c.get(objpath, "")
     52 	if err != nil {
     53 		return nil, err
     54 	}
     55 	defer resp.Body.Close()
     56 	if resp.StatusCode == http.StatusNotFound {
     57 		return nil, ErrNotExist
     58 	}
     59 	iresp, err := parseResponse(resp.Body)
     60 	if err != nil {
     61 		return nil, fmt.Errorf("parse response: %v", err)
     62 	} else if iresp.Error != nil {
     63 		return nil, iresp.Error
     64 	} else if resp.StatusCode != http.StatusOK {
     65 		return nil, errors.New(resp.Status)
     66 	}
     67 	return objectFromLookup(iresp)
     68 }
     69 
     70 func (c *Client) filterObjects(objpath, expr string) ([]object, error) {
     71 	resp, err := c.get(objpath, expr)
     72 	if err != nil {
     73 		return nil, err
     74 	}
     75 	defer resp.Body.Close()
     76 	iresp, err := parseResponse(resp.Body)
     77 	if err != nil {
     78 		return nil, fmt.Errorf("parse response: %v", err)
     79 	} else if iresp.Error != nil {
     80 		return nil, iresp.Error
     81 	} else if resp.StatusCode != http.StatusOK {
     82 		return nil, errors.New(resp.Status)
     83 	} else if len(iresp.Results) == 0 {
     84 		return nil, ErrNoMatch
     85 	}
     86 	return iresp.Results, nil
     87 }
     88 
     89 func (c *Client) createObject(obj object) error {
     90 	b, err := jsonForCreate(obj)
     91 	if err != nil {
     92 		return fmt.Errorf("marshal into json: %v", err)
     93 	}
     94 	resp, err := c.put(obj.path(), bytes.NewReader(b))
     95 	if err != nil {
     96 		return err
     97 	}
     98 	if resp.StatusCode == http.StatusOK {
     99 		return nil
    100 	}
    101 	defer resp.Body.Close()
    102 	iresp, err := parseResponse(resp.Body)
    103 	if err != nil {
    104 		return fmt.Errorf("parse response: %v", err)
    105 	}
    106 	if strings.Contains(iresp.Error.Error(), "already exists") {
    107 		return ErrExist
    108 	}
    109 	return iresp.Error
    110 }
    111 
    112 func (c *Client) deleteObject(objpath string, cascade bool) error {
    113 	resp, err := c.delete(objpath, cascade)
    114 	if err != nil {
    115 		return err
    116 	}
    117 	defer resp.Body.Close()
    118 	if resp.StatusCode == http.StatusOK {
    119 		return nil
    120 	} else if resp.StatusCode == http.StatusNotFound {
    121 		return ErrNotExist
    122 	}
    123 	iresp, err := parseResponse(resp.Body)
    124 	if err != nil {
    125 		return fmt.Errorf("parse response: %v", err)
    126 	}
    127 	return iresp.Error
    128 }