diff --git a/README.md b/README.md index 8455b54..8f410f5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Go zabbix api -[![GoDoc](https://godoc.org/github.com/claranet/go-zabbix-api?status.svg)](https://godoc.org/github.com/claranet/go-zabbix-api) [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Build Status](https://travis-ci.org/claranet/go-zabbix-api.svg?branch=master)](https://travis-ci.org/claranet/go-zabbix-api) +Note, this is not tested and is adjusted for use of tpretz/terraform-provider-zabbix + +[![GoDoc](https://godoc.org/github.com/tpretz/go-zabbix-api?status.svg)](https://godoc.org/github.com/tpretz/go-zabbix-api) [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Build Status](https://travis-ci.org/tpretz/go-zabbix-api.svg?branch=master)](https://travis-ci.org/tpretz/go-zabbix-api) This Go package provides access to Zabbix API. @@ -10,7 +12,7 @@ This package aims to support multiple zabbix resources from its API like trigger ## Install -Install it: `go get github.com/claranet/go-zabbix-api` +Install it: `go get github.com/tpretz/go-zabbix-api` ## Getting started @@ -20,7 +22,7 @@ package main import ( "fmt" - "github.com/claranet/go-zabbix-api" + "github.com/tpretz/go-zabbix-api" ) func main() { @@ -67,7 +69,7 @@ go test -v ## References -Documentation is available on [godoc.org](https://godoc.org/github.com/claranet/go-zabbix-api). +Documentation is available on [godoc.org](https://godoc.org/github.com/tpretz/go-zabbix-api). Also, Rafael Fernandes dos Santos wrote a [great article](http://www.sourcecode.net.br/2014/02/zabbix-api-with-golang.html) about using and extending this package. License: Simplified BSD License (see [LICENSE](LICENSE)). diff --git a/application_test.go b/application_test.go index 3ab7cbf..3f6ef0c 100644 --- a/application_test.go +++ b/application_test.go @@ -6,7 +6,7 @@ import ( "reflect" "testing" - zapi "github.com/claranet/go-zabbix-api" + zapi "github.com/tpretz/go-zabbix-api" ) func CreateApplication(host *zapi.Host, t *testing.T) *zapi.Application { diff --git a/base.go b/base.go index c7b5902..e7e4340 100644 --- a/base.go +++ b/base.go @@ -2,11 +2,13 @@ package zabbix import ( "bytes" + "crypto/tls" "encoding/json" "fmt" "io/ioutil" "log" "net/http" + "sync" "sync/atomic" ) @@ -75,14 +77,44 @@ type API struct { url string c http.Client id int32 + ex sync.Mutex + Config Config +} + +type Config struct { + Url string + TlsNoVerify bool + Log *log.Logger + Serialize bool + Version int } // NewAPI Creates new API access object. // Typical URL is http://host/api_jsonrpc.php or http://host/zabbix/api_jsonrpc.php. // It also may contain HTTP basic auth username and password like // http://username:password@host/api_jsonrpc.php. -func NewAPI(url string) (api *API) { - return &API{url: url, c: http.Client{}, UserAgent: "github.com/claranet/zabbix"} +func NewAPI(c Config) (api *API) { + api = &API{ + url: c.Url, + c: http.Client{}, + UserAgent: "github.com/tpretz/go-zabbix-api", + Logger: c.Log, + Config: c, + } + + if c.TlsNoVerify { + tr := &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + } + api.c = http.Client{ + Transport: tr, + } + api.printf("TLS running in insecure mode, do not use this configuration in production") + } + + return } // SetClient Allows one to use specific http.Client, for example with InsecureSkipVerify transport. @@ -113,6 +145,11 @@ func (api *API) callBytes(method string, params interface{}) (b []byte, err erro req.Header.Add("Content-Type", "application/json-rpc") req.Header.Add("User-Agent", api.UserAgent) + if api.Config.Serialize { + api.ex.Lock() + defer api.ex.Unlock() + } + res, err := api.c.Do(req) if err != nil { api.printf("Error : %s", err) diff --git a/base_test.go b/base_test.go index 2435d45..3aae2e5 100644 --- a/base_test.go +++ b/base_test.go @@ -9,7 +9,7 @@ import ( "testing" "time" - zapi "github.com/claranet/go-zabbix-api" + zapi "github.com/tpretz/go-zabbix-api" ) var ( @@ -42,7 +42,12 @@ func getAPI(t *testing.T) *zapi.API { } url, user, password := os.Getenv("TEST_ZABBIX_URL"), os.Getenv("TEST_ZABBIX_USER"), os.Getenv("TEST_ZABBIX_PASSWORD") - _api = zapi.NewAPI(url) + + // Zabbix client connection configuration + var c zapi.Config + c.Url = url + + _api = zapi.NewAPI(c) _api.SetClient(http.DefaultClient) v := os.Getenv("TEST_ZABBIX_VERBOSE") if v != "" && v != "0" { @@ -84,10 +89,3 @@ func TestVersion(t *testing.T) { t.Errorf("Unexpected version: %s", v) } } - -func ExampleAPI_Call() { - api := zapi.NewAPI("http://host/api_jsonrpc.php") - api.Login("user", "password") - res, _ := api.Call("item.get", zapi.Params{"itemids": "23970", "output": "extend"}) - log.Print(res) -} diff --git a/doc.go b/doc.go index 5f22e7f..cf45cd2 100644 --- a/doc.go +++ b/doc.go @@ -5,7 +5,7 @@ language and the Zabbix monitoring API. Tested on Zabbix 3.2 but should work since 2.0 version. This package aims to support multiple zabbix resources from its API like trigger, application, host group, host, item, template.. -Install it: `go get github.com/claranet/go-zabbix-api` +Install it: `go get github.com/tpretz/go-zabbix-api` Getting started @@ -14,7 +14,7 @@ Getting started import ( "fmt" - "github.com/claranet/go-zabbix-api" + "github.com/tpretz/go-zabbix-api" ) func main() { diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..d2d5db9 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/tpretz/go-zabbix-api + +go 1.12 + +require github.com/AlekSi/reflector v0.4.1 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..ff2e10c --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/AlekSi/reflector v0.4.1/go.mod h1:K9Yt9Jbte9Xw4QZ3e/ovaWduyRSlKVmwnze4z3+bVxs= +github.com/tpretz/go-zabbix-api v0.3.1/go.mod h1:vCzbm8q1QYUHmeWisZSfJzt5MfPj+JeRoNW5o4sG72o= +github.com/tpretz/go-zabbix-api v0.8.0 h1:5xlz9QCcwApIvrPru/WzTUkPltlo+x8tBpbExW9mrjU= +github.com/tpretz/go-zabbix-api v0.8.0/go.mod h1:SFemU2FNM7aeT3/NinjDw0SQEZGVOoU5d+CqXKTetbw= diff --git a/graph.go b/graph.go new file mode 100644 index 0000000..ec2f16e --- /dev/null +++ b/graph.go @@ -0,0 +1,229 @@ +package zabbix + +type ( + GraphType string + GraphAxis string + + GraphItemFunc string + GraphItemDraw string + GraphItemType string + GraphItemSide string +) + +const ( + GraphNormal GraphType = "0" + GraphStacked GraphType = "1" + GraphPie GraphType = "2" + GraphExploded GraphType = "3" + + GraphAxisCalculated GraphAxis = "0" + GraphAxisFixed GraphAxis = "1" + GraphAxisItem GraphAxis = "2" + + GraphItemMin GraphItemFunc = "1" + GraphItemAvg GraphItemFunc = "2" + GraphItemMax GraphItemFunc = "4" + GraphItemAll GraphItemFunc = "7" + GraphItemLast GraphItemFunc = "9" + + GraphItemLine GraphItemDraw = "0" + GraphItemFilled GraphItemDraw = "1" + GraphItemBold GraphItemDraw = "2" + GraphItemDot GraphItemDraw = "3" + GraphItemDashed GraphItemDraw = "4" + GraphItemGradient GraphItemDraw = "5" + + GraphItemSimple GraphItemType = "0" + GraphItemSum GraphItemType = "2" + + GraphItemLeft GraphItemSide = "0" + GraphItemRight GraphItemSide = "1" +) + +type GraphItem struct { + GItemID string `json:"gitemid,omitempty"` + GraphID string `json:"graphid,omitempty"` + Color string `json:"color"` + ItemID string `json:"itemid"` + CalcFunc GraphItemFunc `json:"calc_fnc,omitempty"` + DrawType GraphItemDraw `json:"drawtype,omitempty"` + SortOrder string `json:"sortorder,omitempty"` + Type GraphItemType `json:"type,omitempty"` + YAxisSide GraphItemSide `json:"yaxisside,omitempty"` +} + +type GraphItems []GraphItem + +// Graph represent Zabbix Graph object +// https://www.zabbix.com/documentation/3.2/manual/api/reference/graph/object +type Graph struct { + GraphID string `json:"graphid,omitempty"` + Name string `json:"name"` + Height string `json:"height"` + Width string `json:"width"` + Type GraphType `json:"graphtype,omitempty"` + PercentLeft string `json:"percent_left,omitempty"` + PercentRight string `json:"percent_right,omitempty"` + Show3d string `json:"show_3d,omitempty"` + ShowLegend string `json:"show_legend,omitempty"` + ShowWorkPeriod string `json:"show_work_period,omitempty"` + YMax string `json:"yaxismax,omitempty"` + YMaxItemId string `json:"ymax_itemid,omitempty"` + YMaxType GraphAxis `json:"ymax_type,omitempty"` + YMin string `json:"yaxismin,omitempty"` + YMinItemId string `json:"ymin_itemid,omitempty"` + YMinType GraphAxis `json:"ymin_type,omitempty"` + + GraphItems GraphItems `json:"gitems,omitempty"` +} + +// HostGroups is an array of HostGroup +type Graphs []Graph + +// GraphsGet Wrapper for graph.get +// https://www.zabbix.com/documentation/3.2/manual/api/reference/graph/get +func (api *API) GraphsGet(params Params) (res Graphs, err error) { + if _, present := params["output"]; !present { + params["output"] = "extend" + } + err = api.CallWithErrorParse("graph.get", params, &res) + return +} +func (api *API) GraphProtosGet(params Params) (res Graphs, err error) { + if _, present := params["output"]; !present { + params["output"] = "extend" + } + err = api.CallWithErrorParse("graphprototype.get", params, &res) + return +} + +// GraphGetByID Gets host group by Id only if there is exactly 1 matching host group. +func (api *API) GraphGetByID(id string) (res *Graph, err error) { + groups, err := api.GraphsGet(Params{"graphids": id}) + if err != nil { + return + } + + if len(groups) == 1 { + res = &groups[0] + } else { + e := ExpectedOneResult(len(groups)) + err = &e + } + return +} +func (api *API) GraphProtoGetByID(id string) (res *Graph, err error) { + groups, err := api.GraphProtosGet(Params{"graphids": id}) + if err != nil { + return + } + + if len(groups) == 1 { + res = &groups[0] + } else { + e := ExpectedOneResult(len(groups)) + err = &e + } + return +} + +// GraphsCreate Wrapper for graph.create +// https://www.zabbix.com/documentation/3.2/manual/api/reference/graph/create +func (api *API) GraphsCreate(hostGroups Graphs) (err error) { + response, err := api.CallWithError("graph.create", hostGroups) + if err != nil { + return + } + + result := response.Result.(map[string]interface{}) + groupids := result["graphids"].([]interface{}) + for i, id := range groupids { + hostGroups[i].GraphID = id.(string) + } + return +} +func (api *API) GraphProtosCreate(hostGroups Graphs) (err error) { + response, err := api.CallWithError("graphprototype.create", hostGroups) + if err != nil { + return + } + + result := response.Result.(map[string]interface{}) + groupids := result["graphids"].([]interface{}) + for i, id := range groupids { + hostGroups[i].GraphID = id.(string) + } + return +} + +// GraphsUpdate Wrapper for graph.update +// https://www.zabbix.com/documentation/3.2/manual/api/reference/graph/update +func (api *API) GraphsUpdate(hostGroups Graphs) (err error) { + _, err = api.CallWithError("graph.update", hostGroups) + return +} +func (api *API) GraphProtosUpdate(hostGroups Graphs) (err error) { + _, err = api.CallWithError("graphprototype.update", hostGroups) + return +} + +// HostGroupsDelete Wrapper for hostgroup.delete +// Cleans GroupId in all hostGroups elements if call succeed. +// https://www.zabbix.com/documentation/3.2/manual/api/reference/hostgroup/delete +func (api *API) GraphsDelete(hostGroups Graphs) (err error) { + ids := make([]string, len(hostGroups)) + for i, group := range hostGroups { + ids[i] = group.GraphID + } + + err = api.GraphsDeleteByIds(ids) + if err == nil { + for i := range hostGroups { + hostGroups[i].GraphID = "" + } + } + return +} +func (api *API) GraphProtosDelete(hostGroups Graphs) (err error) { + ids := make([]string, len(hostGroups)) + for i, group := range hostGroups { + ids[i] = group.GraphID + } + + err = api.GraphProtosDeleteByIds(ids) + if err == nil { + for i := range hostGroups { + hostGroups[i].GraphID = "" + } + } + return +} + +// HostGroupsDeleteByIds Wrapper for hostgroup.delete +// https://www.zabbix.com/documentation/3.2/manual/api/reference/hostgroup/delete +func (api *API) GraphsDeleteByIds(ids []string) (err error) { + response, err := api.CallWithError("graph.delete", ids) + if err != nil { + return + } + + result := response.Result.(map[string]interface{}) + groupids := result["graphids"].([]interface{}) + if len(ids) != len(groupids) { + err = &ExpectedMore{len(ids), len(groupids)} + } + return +} +func (api *API) GraphProtosDeleteByIds(ids []string) (err error) { + response, err := api.CallWithError("graphprototype.delete", ids) + if err != nil { + return + } + + result := response.Result.(map[string]interface{}) + groupids := result["graphids"].([]interface{}) + if len(ids) != len(groupids) { + err = &ExpectedMore{len(ids), len(groupids)} + } + return +} diff --git a/host.go b/host.go index 37916eb..90f4209 100644 --- a/host.go +++ b/host.go @@ -1,5 +1,7 @@ package zabbix +import "encoding/json" + type ( // AvailableType (readonly) Availability of Zabbix agent // see "available" in: https://www.zabbix.com/documentation/3.2/manual/api/reference/host/object @@ -8,6 +10,8 @@ type ( // StatusType Status and function of the host. // see "status" in: https://www.zabbix.com/documentation/3.2/manual/api/reference/host/object StatusType int + + InventoryMode int ) const ( @@ -19,6 +23,12 @@ const ( Unavailable AvailableType = 2 ) +const ( + InventoryDisabled InventoryMode = -1 + InventoryManual InventoryMode = 0 + InventoryAutomatic InventoryMode = 1 +) + const ( // Monitored monitored host(default) Monitored StatusType = 0 @@ -29,17 +39,29 @@ const ( // Host represent Zabbix host object // https://www.zabbix.com/documentation/3.2/manual/api/reference/host/object type Host struct { - HostID string `json:"hostid,omitempty"` - Host string `json:"host"` - Available AvailableType `json:"available,string"` - Error string `json:"error"` - Name string `json:"name"` - Status StatusType `json:"status,string"` + HostID string `json:"hostid,omitempty"` + Host string `json:"host"` + Available AvailableType `json:"available,string"` + Error string `json:"error"` + Name string `json:"name"` + Status StatusType `json:"status,string"` + UserMacros Macros `json:"macros,omitempty"` + + RawInventory json.RawMessage `json:"inventory,omitempty"` + Inventory Inventory `json:"-"` + + RawInventoryMode *InventoryMode `json:"inventory_mode,string,omitempty"` + InventoryMode InventoryMode `json:"-"` // Fields below used only when creating hosts - GroupIds HostGroupIDs `json:"groups,omitempty"` - Interfaces HostInterfaces `json:"interfaces,omitempty"` - TemplateIDs TemplateIDs `json:"templates,omitempty"` + GroupIds HostGroupIDs `json:"groups,omitempty"` + Interfaces HostInterfaces `json:"interfaces,omitempty"` + TemplateIDs TemplateIDs `json:"templates,omitempty"` + TemplateIDsClear TemplateIDs `json:"templates_clear,omitempty"` + // templates are read back from this one + ParentTemplateIDs TemplateIDs `json:"parentTemplates,omitempty"` + ProxyID string `json:"proxy_hostid,omitempty"` + Tags Tags `json:"tags,omitempty"` } // Hosts is an array of Host @@ -52,6 +74,58 @@ func (api *API) HostsGet(params Params) (res Hosts, err error) { params["output"] = "extend" } err = api.CallWithErrorParse("host.get", params, &res) + + // fix up host details if present + for i := 0; i < len(res); i++ { + h := res[i] + for j := 0; j < len(h.Interfaces); j++ { + in := h.Interfaces[j] + res[i].Interfaces[j].Details = nil + if len(in.RawDetails) == 0 { + continue + } + + asStr := string(in.RawDetails) + if asStr == "[]" { + continue + } + + out := HostInterfaceDetail{} + // assume singular, if api changes, this will fault + err := json.Unmarshal(in.RawDetails, &out) + if err != nil { + api.printf("got error during unmarshal %s", err) + panic(err) + } + res[i].Interfaces[j].Details = &out + } + + // omitted = disabled + if h.RawInventoryMode == nil { + res[i].InventoryMode = InventoryDisabled + } else { + res[i].InventoryMode = *h.RawInventoryMode + } + + // fix up host inventory if present + if len(h.RawInventory) != 0 { + // if its an empty array + asStr := string(h.RawInventory) + if asStr == "[]" || asStr == "{}" { + continue + } + + // lets unbox + var inv Inventory + if err := json.Unmarshal(h.RawInventory, &inv); err != nil { + api.printf("got error during unmarshal %s", err) + panic(err) + } + res[i].Inventory = inv + } + + } + return } @@ -101,9 +175,33 @@ func (api *API) HostGetByHost(host string) (res *Host, err error) { return } +// handle manual marshal +func prepHosts(hosts Hosts) { + for i := 0; i < len(hosts); i++ { + h := hosts[i] + for j := 0; j < len(h.Interfaces); j++ { + in := h.Interfaces[j] + + if in.Details == nil { + continue + } + + asB, _ := json.Marshal(in.Details) + hosts[i].Interfaces[j].RawDetails = json.RawMessage(asB) + } + if h.Inventory != nil { + asB, _ := json.Marshal(h.Inventory) + hosts[i].RawInventory = json.RawMessage(asB) + } + invMode := h.InventoryMode + h.RawInventoryMode = &invMode + } +} + // HostsCreate Wrapper for host.create // https://www.zabbix.com/documentation/3.2/manual/api/reference/host/create func (api *API) HostsCreate(hosts Hosts) (err error) { + prepHosts(hosts) response, err := api.CallWithError("host.create", hosts) if err != nil { return @@ -120,6 +218,7 @@ func (api *API) HostsCreate(hosts Hosts) (err error) { // HostsUpdate Wrapper for host.update // https://www.zabbix.com/documentation/3.2/manual/api/reference/host/update func (api *API) HostsUpdate(hosts Hosts) (err error) { + prepHosts(hosts) _, err = api.CallWithError("host.update", hosts) return } diff --git a/host_group_test.go b/host_group_test.go index 30a8c05..a12556f 100644 --- a/host_group_test.go +++ b/host_group_test.go @@ -6,7 +6,7 @@ import ( "reflect" "testing" - zapi "github.com/claranet/go-zabbix-api" + zapi "github.com/tpretz/go-zabbix-api" ) func CreateHostGroup(t *testing.T) *zapi.HostGroup { diff --git a/host_interface.go b/host_interface.go index f50b4aa..d0c4507 100644 --- a/host_interface.go +++ b/host_interface.go @@ -1,8 +1,10 @@ package zabbix +import "encoding/json" + type ( // InterfaceType different interface type - InterfaceType int + InterfaceType string ) const ( @@ -10,25 +12,43 @@ const ( // see "type" in https://www.zabbix.com/documentation/3.2/manual/api/reference/hostinterface/object // Agent type - Agent InterfaceType = 1 + Agent InterfaceType = "1" // SNMP type - SNMP InterfaceType = 2 + SNMP InterfaceType = "2" // IPMI type - IPMI InterfaceType = 3 + IPMI InterfaceType = "3" // JMX type - JMX InterfaceType = 4 + JMX InterfaceType = "4" ) // HostInterface represents zabbix host interface type // https://www.zabbix.com/documentation/3.2/manual/api/reference/hostinterface/object type HostInterface struct { - DNS string `json:"dns"` - IP string `json:"ip"` - Main int `json:"main"` - Port string `json:"port"` - Type InterfaceType `json:"type"` - UseIP int `json:"useip"` + InterfaceID string `json:"interfaceid,omitempty"` + DNS string `json:"dns"` + IP string `json:"ip"` + Main string `json:"main"` + Port string `json:"port"` + Type InterfaceType `json:"type"` + UseIP string `json:"useip"` + RawDetails json.RawMessage `json:"details,omitempty"` + Details *HostInterfaceDetail `json:"-"` } // HostInterfaces is an array of HostInterface type HostInterfaces []HostInterface + +type HostInterfaceDetail struct { + Version string `json:"version,omitempty"` + Bulk string `json:"bulk,omitempty"` + Community string `json:"community,omitempty"` + SecurityName string `json:"securityname,omitempty"` + SecurityLevel string `json:"securitylevel,omitempty"` + AuthPassphrase string `json:"authpassphrase,omitempty"` + PrivPassphrase string `json:"privpassphrase,omitempty"` + AuthProtocol string `json:"authprotocol,omitempty"` + PrivProtocol string `json:"privprotocol,omitempty"` + ContextName string `json:"contextname,omitempty"` +} + +type HostInterfaceDetails []HostInterfaceDetail diff --git a/host_test.go b/host_test.go index dc29a6a..7ef6670 100644 --- a/host_test.go +++ b/host_test.go @@ -6,12 +6,12 @@ import ( "reflect" "testing" - zapi "github.com/claranet/go-zabbix-api" + zapi "github.com/tpretz/go-zabbix-api" ) func CreateHost(group *zapi.HostGroup, t *testing.T) *zapi.Host { name := fmt.Sprintf("%s-%d", getHost(), rand.Int()) - iface := zapi.HostInterface{DNS: name, Port: "42", Type: zapi.Agent, UseIP: 0, Main: 1} + iface := zapi.HostInterface{DNS: name, Port: "42", Type: zapi.Agent, UseIP: "0", Main: "1"} hosts := zapi.Hosts{{ Host: name, Name: "Name for " + name, @@ -53,6 +53,7 @@ func TestHosts(t *testing.T) { } host.GroupIds = nil host.Interfaces = nil + host.ProxyID = "0" newName := fmt.Sprintf("%s-%d", getHost(), rand.Int()) host.Host = newName diff --git a/inventory.go b/inventory.go new file mode 100644 index 0000000..0fa8f6f --- /dev/null +++ b/inventory.go @@ -0,0 +1,4 @@ +package zabbix + +// https://www.zabbix.com/documentation/5.0/manual/api/reference/host/object#host_inventory +type Inventory map[string]string diff --git a/item.go b/item.go index 8b98b2a..780e87a 100644 --- a/item.go +++ b/item.go @@ -1,6 +1,7 @@ package zabbix import ( + "encoding/json" "fmt" ) @@ -53,7 +54,11 @@ const ( // Calculated type Calculated ItemType = 15 // JMXAgent type - JMXAgent ItemType = 16 + JMXAgent ItemType = 16 + SNMPTrap ItemType = 17 + Dependent ItemType = 18 + HTTPAgent ItemType = 19 + SNMPAgent ItemType = 20 ) const ( @@ -98,6 +103,8 @@ const ( Delta DeltaType = 2 ) +type HttpHeaders map[string]string + // Item represent Zabbix item object // https://www.zabbix.com/documentation/3.2/manual/api/reference/item/object type Item struct { @@ -112,15 +119,66 @@ type Item struct { DataType DataType `json:"data_type,string"` Delta DeltaType `json:"delta,string"` Description string `json:"description"` - Error string `json:"error"` + Error string `json:"error,omitempty"` History string `json:"history,omitempty"` Trends string `json:"trends,omitempty"` TrapperHosts string `json:"trapper_hosts,omitempty"` + Params string `json:"params,omitempty"` - // Fields below used only when creating applications - ApplicationIds []string `json:"applications,omitempty"` + // list of strings on set, but list of objects on get + RawApplications json.RawMessage `json:"applications,omitempty"` + Applications []string `json:"-"` ItemParent Hosts `json:"hosts"` + + Preprocessors Preprocessors `json:"preprocessing,omitempty"` + + // HTTP Agent Fields + Url string `json:"url,omitempty"` + RequestMethod string `json:"request_method,omitempty"` + PostType string `json:"post_type,omitempty"` + RetrieveMode string `json:"retrieve_mode,omitempty"` + Posts string `json:"posts,omitempty"` + StatusCodes string `json:"status_codes,omitempty"` + Timeout string `json:"timeout,omitempty"` + VerifyHost string `json:"verify_host,omitempty"` + VerifyPeer string `json:"verify_peer,omitempty"` + AuthType string `json:"authtype,omitempty"` + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty"` + Headers HttpHeaders `json:"-"` + RawHeaders json.RawMessage `json:"headers,omitempty"` + Proxy string `json:"http_proxy,omitempty"` + FollowRedirects string `json:"follow_redirects,omitempty"` + + // SNMP Fields + SNMPOid string `json:"snmp_oid,omitempty"` + SNMPCommunity string `json:"snmp_community,omitempty"` + SNMPv3AuthPassphrase string `json:"snmpv3_authpassphrase,omitempty"` + SNMPv3AuthProtocol string `json:"snmpv3_authprotocol,omitempty"` + SNMPv3ContextName string `json:"snmpv3_contextname,omitempty"` + SNMPv3PrivPasshrase string `json:"snmpv3_privpassphrase,omitempty"` + SNMPv3PrivProtocol string `json:"snmpv3_privprotocol,omitempty"` + SNMPv3SecurityLevel string `json:"snmpv3_securitylevel,omitempty"` + SNMPv3SecurityName string `json:"snmpv3_securityname,omitempty"` + + // Dependent Fields + MasterItemID string `json:"master_itemid,omitempty"` + + // Prototype + RuleID string `json:"ruleid,omitempty"` + DiscoveryRule *LLDRule `json:"discoveryRule,omitEmpty"` + + Tags Tags `json:"tags,omitempty"` +} + +type Preprocessors []Preprocessor + +type Preprocessor struct { + Type string `json:"type,omitempty"` + Params string `json:"params"` + ErrorHandler string `json:"error_handler,omitempty"` + ErrorHandlerParams string `json:"error_handler_params"` } // Items is an array of Item @@ -146,9 +204,77 @@ func (api *API) ItemsGet(params Params) (res Items, err error) { params["output"] = "extend" } err = api.CallWithErrorParse("item.get", params, &res) + api.itemsHeadersUnmarshal(res) + return +} +func (api *API) ProtoItemsGet(params Params) (res Items, err error) { + if _, present := params["output"]; !present { + params["output"] = "extend" + } + err = api.CallWithErrorParse("itemprototype.get", params, &res) + api.itemsHeadersUnmarshal(res) return } +func (api *API) itemsHeadersUnmarshal(item Items) { + for i := 0; i < len(item); i++ { + h := item[i] + + if len(h.RawApplications) != 0 { + asStr := string(h.RawApplications) + if asStr != "[]" { + var applications Applications + err := json.Unmarshal(h.RawApplications, &applications) + if err != nil { + panic(err) + } + ids := []string{} + for _, a := range applications { + ids = append(ids, a.ApplicationID) + } + item[i].Applications = ids + } + } + + item[i].Headers = HttpHeaders{} + + if len(h.RawHeaders) == 0 { + continue + } + + asStr := string(h.RawHeaders) + if asStr == "[]" { + continue + } + + out := HttpHeaders{} + err := json.Unmarshal(h.RawHeaders, &out) + if err != nil { + api.printf("got error during unmarshal %s", err) + panic(err) + } + item[i].Headers = out + } +} + +func prepItems(item Items) { + for i := 0; i < len(item); i++ { + h := item[i] + + if h.Applications != nil { + text, _ := json.Marshal(h.Applications) + raw := json.RawMessage(text) + h.RawApplications = raw + } + + if h.Headers == nil { + continue + } + asB, _ := json.Marshal(h.Headers) + item[i].RawHeaders = json.RawMessage(asB) + } +} + // ItemGetByID Gets item by Id only if there is exactly 1 matching host. func (api *API) ItemGetByID(id string) (res *Item, err error) { items, err := api.ItemsGet(Params{"itemids": id}) @@ -164,15 +290,33 @@ func (api *API) ItemGetByID(id string) (res *Item, err error) { res = &items[0] return } +func (api *API) ProtoItemGetByID(id string) (res *Item, err error) { + items, err := api.ProtoItemsGet(Params{"itemids": id}) + if err != nil { + return + } + + if len(items) != 1 { + e := ExpectedOneResult(len(items)) + err = &e + return + } + res = &items[0] + return +} // ItemsGetByApplicationID Gets items by application Id. func (api *API) ItemsGetByApplicationID(id string) (res Items, err error) { return api.ItemsGet(Params{"applicationids": id}) } +func (api *API) ProtoItemsGetByApplicationID(id string) (res Items, err error) { + return api.ProtoItemsGet(Params{"applicationids": id}) +} // ItemsCreate Wrapper for item.create // https://www.zabbix.com/documentation/3.2/manual/api/reference/item/create func (api *API) ItemsCreate(items Items) (err error) { + prepItems(items) response, err := api.CallWithError("item.create", items) if err != nil { return @@ -185,13 +329,33 @@ func (api *API) ItemsCreate(items Items) (err error) { } return } +func (api *API) ProtoItemsCreate(items Items) (err error) { + prepItems(items) + response, err := api.CallWithError("itemprototype.create", items) + if err != nil { + return + } + + result := response.Result.(map[string]interface{}) + itemids := result["itemids"].([]interface{}) + for i, id := range itemids { + items[i].ItemID = id.(string) + } + return +} // ItemsUpdate Wrapper for item.update // https://www.zabbix.com/documentation/3.2/manual/api/reference/item/update func (api *API) ItemsUpdate(items Items) (err error) { + prepItems(items) _, err = api.CallWithError("item.update", items) return } +func (api *API) ProtoItemsUpdate(items Items) (err error) { + prepItems(items) + _, err = api.CallWithError("itemprototype.update", items) + return +} // ItemsDelete Wrapper for item.delete // Cleans ItemId in all items elements if call succeed. @@ -210,6 +374,20 @@ func (api *API) ItemsDelete(items Items) (err error) { } return } +func (api *API) ProtoItemsDelete(items Items) (err error) { + ids := make([]string, len(items)) + for i, item := range items { + ids[i] = item.ItemID + } + + err = api.ProtoItemsDeleteByIds(ids) + if err == nil { + for i := range items { + items[i].ItemID = "" + } + } + return +} // ItemsDeleteByIds Wrapper for item.delete // https://www.zabbix.com/documentation/3.2/manual/api/reference/item/delete @@ -224,6 +402,17 @@ func (api *API) ItemsDeleteByIds(ids []string) (err error) { } return } +func (api *API) ProtoItemsDeleteByIds(ids []string) (err error) { + deleteIds, err := api.ProtoItemsDeleteIDs(ids) + if err != nil { + return + } + l := len(deleteIds) + if len(ids) != l { + err = &ExpectedMore{len(ids), l} + } + return +} // ItemsDeleteIDs Wrapper for item.delete // Delete the item and return the id of the deleted item @@ -245,3 +434,21 @@ func (api *API) ItemsDeleteIDs(ids []string) (itemids []interface{}, err error) } return } +func (api *API) ProtoItemsDeleteIDs(ids []string) (itemids []interface{}, err error) { + response, err := api.CallWithError("itemprototype.delete", ids) + if err != nil { + return + } + + result := response.Result.(map[string]interface{}) + itemids1, ok := result["prototypeids"].([]interface{}) + if !ok { + itemids2 := result["prototypeids"].(map[string]interface{}) + for _, id := range itemids2 { + itemids = append(itemids, id) + } + } else { + itemids = itemids1 + } + return +} diff --git a/item_test.go b/item_test.go index 23af6b8..1041cbc 100644 --- a/item_test.go +++ b/item_test.go @@ -3,16 +3,15 @@ package zabbix_test import ( "testing" - zapi "github.com/claranet/go-zabbix-api" + zapi "github.com/tpretz/go-zabbix-api" ) func CreateItem(app *zapi.Application, t *testing.T) *zapi.Item { items := zapi.Items{{ - HostID: app.HostID, - Key: "key.lala.laa", - Name: "name for key", - Type: zapi.ZabbixTrapper, - ApplicationIds: []string{app.ApplicationID}, + HostID: app.HostID, + Key: "key.lala.laa", + Name: "name for key", + Type: zapi.ZabbixTrapper, }} err := getAPI(t).ItemsCreate(items) if err != nil { diff --git a/lld.go b/lld.go new file mode 100644 index 0000000..ee223ab --- /dev/null +++ b/lld.go @@ -0,0 +1,248 @@ +package zabbix + +import "encoding/json" + +type ( + LLDEvalType string + LLDOperatorType string +) + +const ( + LLDAndOr LLDEvalType = "0" + LLDAnd LLDEvalType = "1" + LLDOr LLDEvalType = "2" + LLDCustom LLDEvalType = "3" + LLDMatch LLDOperatorType = "8" + LLDNotMatch LLDOperatorType = "9" +) + +type LLDRuleFilterCondition struct { + Macro string `json:"macro"` + Value string `json:"value"` + FormulaID string `json:"formulaid,omitempty"` + Operator LLDOperatorType `json:"operator,omitempty"` +} + +type LLDRuleFilterConditions []LLDRuleFilterCondition + +type LLDRuleFilter struct { + Conditions LLDRuleFilterConditions `json:"conditions"` + EvalType LLDEvalType `json:"evaltype"` + EvalFormula string `json:"eval_formula,omitempty"` + Formula string `json:"formula"` +} + +type LLDMacroPath struct { + Macro string `json:"lld_macro"` + Path string `json:"path"` +} + +type LLDMacroPaths []LLDMacroPath + +// Item represent Zabbix lld object +// https://www.zabbix.com/documentation/3.2/manual/api/reference/item/object +type LLDRule struct { + ItemID string `json:"itemid,omitempty"` + Delay string `json:"delay"` + HostID string `json:"hostid"` + InterfaceID string `json:"interfaceid,omitempty"` + Key string `json:"key_"` + Name string `json:"name"` + Type ItemType `json:"type,string"` + // ValueType ValueType `json:"value_type,string"` + // DataType DataType `json:"data_type,string"` + // Delta DeltaType `json:"delta,string"` + AuthType string `json:"authtype,omitempty"` + DelayFlex string `json:"delay_flex,omitempty"` + Description string `json:"description"` + Error string `json:"error,omitempty"` + IpmiSensor string `json:"ipmi_sensor,omitempty"` + LifeTime string `json:"lifetime,omitempty"` + Params string `json:"params,omitempty"` + PrivateKey string `json:"privatekey,omitempty"` + PublicKey string `json:"publickey,omitempty"` + Status string `json:"status,omitempty"` + TrapperHosts string `json:"trapper_hosts,omitempty"` + MasterItemID string `json:"master_itemid,omitempty"` + + // ssh / telnet + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty"` + Port string `json:"port,omitempty"` + + // HTTP Agent Fields + Url string `json:"url,omitempty"` + RequestMethod string `json:"request_method,omitempty"` + AllowTraps string `json:"allow_traps,omitempty"` + PostType string `json:"post_type,omitempty"` + RetrieveMode string `json:"retrieve_mode,omitempty"` + Posts string `json:"posts,omitempty"` + StatusCodes string `json:"status_codes,omitempty"` + Timeout string `json:"timeout,omitempty"` + VerifyHost string `json:"verify_host,omitempty"` + VerifyPeer string `json:"verify_peer,omitempty"` + Headers HttpHeaders `json:"-"` + RawHeaders json.RawMessage `json:"headers,omitempty"` + Proxy string `json:"http_proxy,omitempty"` + FollowRedirects string `json:"follow_redirects,omitempty"` + + // SNMP Fields + SNMPOid string `json:"snmp_oid,omitempty"` + SNMPCommunity string `json:"snmp_community,omitempty"` + SNMPv3AuthPassphrase string `json:"snmpv3_authpassphrase,omitempty"` + SNMPv3AuthProtocol string `json:"snmpv3_authprotocol,omitempty"` + SNMPv3ContextName string `json:"snmpv3_contextname,omitempty"` + SNMPv3PrivPasshrase string `json:"snmpv3_privpassphrase,omitempty"` + SNMPv3PrivProtocol string `json:"snmpv3_privprotocol,omitempty"` + SNMPv3SecurityLevel string `json:"snmpv3_securitylevel,omitempty"` + SNMPv3SecurityName string `json:"snmpv3_securityname,omitempty"` + + Preprocessors Preprocessors `json:"preprocessing,omitempty"` + Filter LLDRuleFilter `json:"filter"` + MacroPaths LLDMacroPaths `json:"lld_macro_paths,omitempty"` +} + +// Items is an array of Item +type LLDRules []LLDRule + +func (api *API) lldsHeadersUnmarshal(item LLDRules) { + for i := 0; i < len(item); i++ { + h := item[i] + + item[i].Headers = HttpHeaders{} + + if len(h.RawHeaders) == 0 { + continue + } + + asStr := string(h.RawHeaders) + if asStr == "[]" { + continue + } + + out := HttpHeaders{} + err := json.Unmarshal(h.RawHeaders, &out) + if err != nil { + api.printf("got error during unmarshal %s", err) + panic(err) + } + item[i].Headers = out + } +} + +func prepLLDs(item LLDRules) { + for i := 0; i < len(item); i++ { + h := item[i] + + if h.Headers == nil { + continue + } + asB, _ := json.Marshal(h.Headers) + item[i].RawHeaders = json.RawMessage(asB) + } +} + +// ItemsGet Wrapper for item.get +// https://www.zabbix.com/documentation/3.2/manual/api/reference/item/get +func (api *API) LLDsGet(params Params) (res LLDRules, err error) { + if _, present := params["output"]; !present { + params["output"] = "extend" + } + err = api.CallWithErrorParse("discoveryrule.get", params, &res) + api.lldsHeadersUnmarshal(res) + return +} + +// ItemGetByID Gets item by Id only if there is exactly 1 matching host. +func (api *API) LLDGetByID(id string) (res *LLDRule, err error) { + items, err := api.LLDsGet(Params{"itemids": id}) + if err != nil { + return + } + + if len(items) != 1 { + e := ExpectedOneResult(len(items)) + err = &e + return + } + res = &items[0] + return +} + +// ItemsCreate Wrapper for item.create +// https://www.zabbix.com/documentation/3.2/manual/api/reference/item/create +func (api *API) LLDsCreate(items LLDRules) (err error) { + prepLLDs(items) + response, err := api.CallWithError("discoveryrule.create", items) + if err != nil { + return + } + + result := response.Result.(map[string]interface{}) + itemids := result["itemids"].([]interface{}) + for i, id := range itemids { + items[i].ItemID = id.(string) + } + return +} + +// ItemsUpdate Wrapper for item.update +// https://www.zabbix.com/documentation/3.2/manual/api/reference/item/update +func (api *API) LLDsUpdate(items LLDRules) (err error) { + prepLLDs(items) + _, err = api.CallWithError("discoveryrule.update", items) + return +} + +// ItemsDelete Wrapper for item.delete +// Cleans ItemId in all items elements if call succeed. +// https://www.zabbix.com/documentation/3.2/manual/api/reference/item/delete +func (api *API) LLDsDelete(items LLDRules) (err error) { + ids := make([]string, len(items)) + for i, item := range items { + ids[i] = item.ItemID + } + + err = api.LLDDeleteByIds(ids) + if err == nil { + for i := range items { + items[i].ItemID = "" + } + } + return +} + +// ItemsDeleteByIds Wrapper for item.delete +// https://www.zabbix.com/documentation/3.2/manual/api/reference/item/delete +func (api *API) LLDDeleteByIds(ids []string) (err error) { + deleteIds, err := api.LLDDeleteIDs(ids) + if err != nil { + return + } + l := len(deleteIds) + if len(ids) != l { + err = &ExpectedMore{len(ids), l} + } + return +} + +// ItemsDeleteIDs Wrapper for item.delete +// Delete the item and return the id of the deleted item +func (api *API) LLDDeleteIDs(ids []string) (itemids []interface{}, err error) { + response, err := api.CallWithError("discoveryrule.delete", ids) + if err != nil { + return + } + + result := response.Result.(map[string]interface{}) + itemids1, ok := result["ruleids"].([]interface{}) + if !ok { + itemids2 := result["ruleids"].(map[string]interface{}) + for _, id := range itemids2 { + itemids = append(itemids, id) + } + } else { + itemids = itemids1 + } + return +} diff --git a/macro.go b/macro.go index 5964155..a09108e 100644 --- a/macro.go +++ b/macro.go @@ -4,7 +4,7 @@ package zabbix // https://www.zabbix.com/documentation/3.2/manual/api/reference/usermacro/object type Macro struct { MacroID string `json:"hostmacroids,omitempty"` - HostID string `json:"hostid"` + HostID string `json:"hostid,omitempty"` MacroName string `json:"macro"` Value string `json:"value"` } diff --git a/proxy.go b/proxy.go new file mode 100644 index 0000000..e4ab8ec --- /dev/null +++ b/proxy.go @@ -0,0 +1,22 @@ +package zabbix + +// Proxy represent Zabbix proxy object +// https://www.zabbix.com/documentation/3.2/manual/api/reference/proxy/object +type Proxy struct { + ProxyID string `json:"proxyid,omitempty"` + Host string `json:"host"` + // add rest later +} + +// Proxies is an array of Proxy +type Proxies []Proxy + +// ProxiesGet Wrapper for proxy.get +// https://www.zabbix.com/documentation/3.2/manual/api/reference/proxy/get +func (api *API) ProxiesGet(params Params) (res Proxies, err error) { + if _, present := params["output"]; !present { + params["output"] = "extend" + } + err = api.CallWithErrorParse("proxy.get", params, &res) + return +} diff --git a/template.go b/template.go index 21ea8e2..3b25c4c 100644 --- a/template.go +++ b/template.go @@ -3,15 +3,16 @@ package zabbix // Template represent Zabbix Template type returned from Zabbix API // https://www.zabbix.com/documentation/3.2/manual/api/reference/template/object type Template struct { - TemplateID string `json:"templateid,omitempty"` - Host string `json:"host"` - Description string `json:"description,omitempty"` - Name string `json:"name,omitempty"` - Groups HostGroups `json:"groups"` - UserMacros Macros `json:"macros"` - LinkedTemplates Templates `json:"templates,omitempty"` - TemplatesClear Templates `json:"templates_clear,omitempty"` - LinkedHosts []string `json:"hosts,omitempty"` + TemplateID string `json:"templateid,omitempty"` + Host string `json:"host"` + Description string `json:"description,omitempty"` + Name string `json:"name,omitempty"` + Groups HostGroupIDs `json:"groups"` + UserMacros Macros `json:"macros"` + LinkedTemplates TemplateIDs `json:"templates,omitempty"` + ParentTemplates TemplateIDs `json:"parentTemplates,omitempty"` + TemplatesClear TemplateIDs `json:"templates_clear,omitempty"` + LinkedHosts []string `json:"hosts,omitempty"` } // Templates is an Array of Template structs. diff --git a/template_test.go b/template_test.go index f8e2027..06ad46f 100644 --- a/template_test.go +++ b/template_test.go @@ -3,13 +3,20 @@ package zabbix_test import ( "testing" - zapi "github.com/claranet/go-zabbix-api" + zapi "github.com/tpretz/go-zabbix-api" ) func CreateTemplate(hostGroup *zapi.HostGroup, t *testing.T) *zapi.Template { + + group := zapi.HostGroupID{ + GroupID: hostGroup.GroupID, + } + + groups := []zapi.HostGroupID{group} + template := zapi.Templates{zapi.Template{ Host: "template name", - Groups: zapi.HostGroups{*hostGroup}, + Groups: groups, }} err := getAPI(t).TemplatesCreate(template) if err != nil { diff --git a/trigger.go b/trigger.go index 15676a0..3601aac 100644 --- a/trigger.go +++ b/trigger.go @@ -39,6 +39,20 @@ const ( Problem ValueType = 1 ) +type Tag struct { + Tag string `json:"tag"` + Value string `json:"value,omitempty"` +} + +type Tags []Tag + +type TriggerID struct { + TriggerID string `json:"triggerid"` +} + +// TemplateIDs is an Array of TemplateID structs. +type TriggerIDs []TriggerID + // TriggerFunction The function objects represents the functions used in the trigger expression type TriggerFunction struct { FunctionID string `json:"functionid"` @@ -60,14 +74,24 @@ type Trigger struct { //TemplateId string `json:"templateid"` //Value ValueType `json:""` + Opdata string `json:"opdata,omitempty"` + Type int `json:"type,string"` + Url string `json:"url,omitempty"` + RecoveryMode int `json:"recovery_mode,string"` + RecoveryExpression string `json:"recovery_expression,omitempty"` + CorrelationMode int `json:"correlation_mode,string"` + CorrelationTag string `json:"correlation_tag,omitempty"` + ManualClose int `json:"manual_close,string"` + Priority SeverityType `json:"priority,string"` Status StatusType `json:"status,string"` - Dependencies Triggers `json:"dependencies,omitempty"` + Dependencies TriggerIDs `json:"dependencies,omitempty"` Functions TriggerFunctions `json:"functions,omitempty"` // Items contained by the trigger in the items property. ContainedItems Items `json:"items,omitempty"` // Hosts that the trigger belongs to in the hosts property. ParentHosts Hosts `json:"hosts,omitempty"` + Tags Tags `json:"tags,omitempty"` } // Triggers is an array of Trigger @@ -82,6 +106,13 @@ func (api *API) TriggersGet(params Params) (res Triggers, err error) { err = api.CallWithErrorParse("trigger.get", params, &res) return } +func (api *API) ProtoTriggersGet(params Params) (res Triggers, err error) { + if _, present := params["output"]; !present { + params["output"] = "extend" + } + err = api.CallWithErrorParse("triggerprototype.get", params, &res) + return +} // TriggerGetByID Gets trigger by Id only if there is exactly 1 matching host. func (api *API) TriggerGetByID(id string) (res *Trigger, err error) { @@ -98,6 +129,20 @@ func (api *API) TriggerGetByID(id string) (res *Trigger, err error) { res = &triggers[0] return } +func (api *API) ProtoTriggerGetByID(id string) (res *Trigger, err error) { + triggers, err := api.ProtoTriggersGet(Params{"triggerids": id}) + if err != nil { + return + } + + if len(triggers) != 1 { + e := ExpectedOneResult(len(triggers)) + err = &e + return + } + res = &triggers[0] + return +} // TriggersCreate Wrapper for trigger.create // https://www.zabbix.com/documentation/3.2/manual/api/reference/trigger/create @@ -114,6 +159,19 @@ func (api *API) TriggersCreate(triggers Triggers) (err error) { } return } +func (api *API) ProtoTriggersCreate(triggers Triggers) (err error) { + response, err := api.CallWithError("triggerprototype.create", triggers) + if err != nil { + return + } + + result := response.Result.(map[string]interface{}) + triggerids := result["triggerids"].([]interface{}) + for i, id := range triggerids { + triggers[i].TriggerID = id.(string) + } + return +} // TriggersUpdate Wrapper for trigger.update // https://www.zabbix.com/documentation/3.2/manual/api/reference/trigger/update @@ -121,6 +179,10 @@ func (api *API) TriggersUpdate(triggers Triggers) (err error) { _, err = api.CallWithError("trigger.update", triggers) return } +func (api *API) ProtoTriggersUpdate(triggers Triggers) (err error) { + _, err = api.CallWithError("triggerprototype.update", triggers) + return +} // TriggersDelete Wrapper for trigger.delete // Cleans ItemId in all triggers elements if call succeed. @@ -139,6 +201,20 @@ func (api *API) TriggersDelete(triggers Triggers) (err error) { } return } +func (api *API) ProtoTriggersDelete(triggers Triggers) (err error) { + ids := make([]string, len(triggers)) + for i, trigger := range triggers { + ids[i] = trigger.TriggerID + } + + err = api.ProtoTriggersDeleteByIds(ids) + if err == nil { + for i := range triggers { + triggers[i].TriggerID = "" + } + } + return +} // TriggersDeleteByIds Wrapper for trigger.delete // https://www.zabbix.com/documentation/3.2/manual/api/reference/trigger/delete @@ -153,6 +229,17 @@ func (api *API) TriggersDeleteByIds(ids []string) (err error) { } return } +func (api *API) ProtoTriggersDeleteByIds(ids []string) (err error) { + deleteIds, err := api.ProtoTriggersDeleteIDs(ids) + if err != nil { + return + } + l := len(deleteIds) + if len(ids) != l { + err = &ExpectedMore{len(ids), l} + } + return +} // TriggersDeleteIDs Wrapper for trigger.delete // return the id of the deleted trigger @@ -174,3 +261,21 @@ func (api *API) TriggersDeleteIDs(ids []string) (triggerids []interface{}, err e } return } +func (api *API) ProtoTriggersDeleteIDs(ids []string) (triggerids []interface{}, err error) { + response, err := api.CallWithError("triggerprototype.delete", ids) + if err != nil { + return + } + + result := response.Result.(map[string]interface{}) + triggerids1, ok := result["triggerids"].([]interface{}) + if !ok { + triggerids2 := result["triggerids"].(map[string]interface{}) + for _, id := range triggerids2 { + triggerids = append(triggerids, id) + } + } else { + triggerids = triggerids1 + } + return +} diff --git a/trigger_test.go b/trigger_test.go index fd8a444..ef63ecb 100644 --- a/trigger_test.go +++ b/trigger_test.go @@ -4,7 +4,7 @@ import ( "fmt" "testing" - zapi "github.com/claranet/go-zabbix-api" + zapi "github.com/tpretz/go-zabbix-api" ) func CreateTrigger(item *zapi.Item, host *zapi.Host, t *testing.T) *zapi.Trigger {