Skip to content

Commit

Permalink
Merge pull request #15 from claranet/zabbix54
Browse files Browse the repository at this point in the history
Add Zabbix 5.4+ compatibility
  • Loading branch information
pdecat authored Oct 4, 2022
2 parents 1651899 + 7531972 commit b0a7b3f
Show file tree
Hide file tree
Showing 15 changed files with 391 additions and 36 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test-zabbix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
fail-fast: false
matrix:
zabbix_version: ["3.0", "3.2", "3.4", "4.0", "4.2", "4.4", "5.0", "5.2"]
zabbix_version: ["3.0", "3.2", "3.4", "4.0", "4.2", "4.4", "5.0", "5.2", "5.4", "6.0", "6.2"]

services:
mysql-server:
Expand Down
2 changes: 2 additions & 0 deletions application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ func testDeleteApplication(app *zapi.Application, t *testing.T) {
}

func TestApplications(t *testing.T) {
skipTestIfVersionGreaterThanOrEqual(t, "5.4", "dropped support for Application API")

api := testGetAPI(t)

group := testCreateHostGroup(t)
Expand Down
34 changes: 34 additions & 0 deletions base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

zapi "github.com/claranet/go-zabbix-api"
"github.com/hashicorp/go-version"
)

var (
Expand Down Expand Up @@ -62,6 +63,39 @@ func testGetAPI(t *testing.T) *zapi.API {
return _api
}

func compVersion(t *testing.T, comparedVersion string) (int, string) {
api := testGetAPI(t)
serverVersion, err := api.Version()
if err != nil {
t.Fatal(err)
}
sVersion, _ := version.NewVersion(serverVersion)
cVersion, _ := version.NewVersion(comparedVersion)
return sVersion.Compare(cVersion), serverVersion
}

func isVersionLessThan(t *testing.T, comparedVersion string) (bool, string) {
comp, serverVersion := compVersion(t, comparedVersion)
return comp < 0, serverVersion
}

func isVersionGreaterThanOrEqual(t *testing.T, comparedVersion string) (bool, string) {
comp, serverVersion := compVersion(t, comparedVersion)
return comp >= 0, serverVersion
}

func skipTestIfVersionGreaterThanOrEqual(t *testing.T, comparedVersion, msg string) {
if compGreaterThanOrEqual, serverVersion := isVersionGreaterThanOrEqual(t, comparedVersion); compGreaterThanOrEqual {
t.Skipf("Zabbix version %s is greater than or equal to %s which %s, skipping test.", serverVersion, comparedVersion, msg)
}
}

func skipTestIfVersionLessThan(t *testing.T, comparedVersion, msg string) {
if compGreaterThanOrEqual, serverVersion := isVersionLessThan(t, comparedVersion); compGreaterThanOrEqual {
t.Skipf("Zabbix version %s is less than to %s which %s, skipping test.", serverVersion, comparedVersion, msg)
}
}

func TestBadCalls(t *testing.T) {
api := testGetAPI(t)
res, err := api.Call("", nil)
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module github.com/claranet/go-zabbix-api

go 1.18

require github.com/hashicorp/go-version v1.6.0 // indirect
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
15 changes: 7 additions & 8 deletions host.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,16 +145,15 @@ func (api *API) HostsDelete(hosts Hosts) (err error) {
// HostsDeleteByIds Wrapper for host.delete
// https://www.zabbix.com/documentation/3.2/manual/api/reference/host/delete
func (api *API) HostsDeleteByIds(ids []string) (err error) {
hostIds := make([]map[string]string, len(ids))
for i, id := range ids {
hostIds[i] = map[string]string{"hostid": id}
}

response, err := api.CallWithError("host.delete", hostIds)
response, err := api.CallWithError("host.delete", ids)
if err != nil {
// Zabbix 2.4 uses new syntax only
if e, ok := err.(*Error); ok && e.Code == -32500 {
response, err = api.CallWithError("host.delete", ids)
// Zabbix 2.0 and older use old syntax only with hostid
hostIds := make([]map[string]string, len(ids))
for i, id := range ids {
hostIds[i] = map[string]string{"hostid": id}
}
response, err = api.CallWithError("host.delete", hostIds)
}
}
if err != nil {
Expand Down
24 changes: 21 additions & 3 deletions item_prototype_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

dd "github.com/claranet/go-zabbix-api"
zapi "github.com/claranet/go-zabbix-api"
)

func testCreateItemPrototype(template *dd.Template, lldRule *dd.LLDRule, t *testing.T) *dd.ItemPrototype {
Expand Down Expand Up @@ -34,10 +35,27 @@ func testDeleteItemPrototype(item *dd.ItemPrototype, t *testing.T) {
func testItemPrototype(t *testing.T) {
api := testGetAPI(t)

hostGroup := testCreateHostGroup(t)
defer testDeleteHostGroup(hostGroup, t)
// Zabbix v6.2 introduced Template Groups and requires them for Templates
var groupIds zapi.HostGroupIDs
if compLessThan, _ := isVersionLessThan(t, "6.2"); compLessThan {
hostGroup := testCreateHostGroup(t)
defer testDeleteHostGroup(hostGroup, t)
groupIds = zapi.HostGroupIDs{
{
GroupID: hostGroup.GroupID,
},
}
} else {
templateGroup := testCreateTemplateGroup(t)
defer testDeleteTemplateGroup(templateGroup, t)
groupIds = zapi.HostGroupIDs{
{
GroupID: templateGroup.GroupID,
},
}
}

template := testCreateTemplate(hostGroup, t)
template := testCreateTemplate(&groupIds, t)
defer testDeleteTemplate(template, t)

lldRule := testCreateLLDRule(template, t)
Expand Down
46 changes: 44 additions & 2 deletions item_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,22 @@ import (
zapi "github.com/claranet/go-zabbix-api"
)

func testCreateItem(app *zapi.Application, t *testing.T) *zapi.Item {
func testCreateItem(host *zapi.Host, t *testing.T) *zapi.Item {
items := zapi.Items{{
HostID: host.HostID,
Key: "key.lala.laa",
Name: "name for key",
Type: zapi.ZabbixTrapper,
Delay: "0",
}}
err := testGetAPI(t).ItemsCreate(items)
if err != nil {
t.Fatal(err)
}
return &items[0]
}

func testCreateItemWithApplication(app *zapi.Application, t *testing.T) *zapi.Item {
items := zapi.Items{{
HostID: app.HostID,
Key: "key.lala.laa",
Expand Down Expand Up @@ -38,6 +53,33 @@ func TestItems(t *testing.T) {
host := testCreateHost(group, t)
defer testDeleteHost(host, t)

item := testCreateItem(host, t)

_, err := api.ItemGetByID(item.ItemID)
if err != nil {
t.Fatal(err)
}

item.Name = "another name"
err = api.ItemsUpdate(zapi.Items{*item})
if err != nil {
t.Error(err)
}

testDeleteItem(item, t)
}

func TestItemsWithApplication(t *testing.T) {
skipTestIfVersionGreaterThanOrEqual(t, "5.4", "dropped support for Application API")

api := testGetAPI(t)

group := testCreateHostGroup(t)
defer testDeleteHostGroup(group, t)

host := testCreateHost(group, t)
defer testDeleteHost(host, t)

app := testCreateApplication(host, t)
defer testDeleteApplication(app, t)

Expand All @@ -49,7 +91,7 @@ func TestItems(t *testing.T) {
t.Fatal("Found items")
}

item := testCreateItem(app, t)
item := testCreateItemWithApplication(app, t)

_, err = api.ItemGetByID(item.ItemID)
if err != nil {
Expand Down
24 changes: 21 additions & 3 deletions lld_rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

dd "github.com/claranet/go-zabbix-api"
zapi "github.com/claranet/go-zabbix-api"
)

func testCreateLLDRule(template *dd.Template, t *testing.T) *dd.LLDRule {
Expand Down Expand Up @@ -42,10 +43,27 @@ func testDeleteLLDRule(rule *dd.LLDRule, t *testing.T) {
func TestLLDRule(t *testing.T) {
api := testGetAPI(t)

hostGroup := testCreateHostGroup(t)
defer testDeleteHostGroup(hostGroup, t)
// Zabbix v6.2 introduced Template Groups and requires them for Templates
var groupIds zapi.HostGroupIDs
if compLessThan, _ := isVersionLessThan(t, "6.2"); compLessThan {
hostGroup := testCreateHostGroup(t)
defer testDeleteHostGroup(hostGroup, t)
groupIds = zapi.HostGroupIDs{
{
GroupID: hostGroup.GroupID,
},
}
} else {
templateGroup := testCreateTemplateGroup(t)
defer testDeleteTemplateGroup(templateGroup, t)
groupIds = zapi.HostGroupIDs{
{
GroupID: templateGroup.GroupID,
},
}
}

template := testCreateTemplate(hostGroup, t)
template := testCreateTemplate(&groupIds, t)
defer testDeleteTemplate(template, t)

lldRule := testCreateLLDRule(template, t)
Expand Down
18 changes: 9 additions & 9 deletions template.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ 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 Hosts `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,omitempty"`
LinkedTemplates Templates `json:"templates,omitempty"`
TemplatesClear Templates `json:"templates_clear,omitempty"`
LinkedHosts Hosts `json:"hosts,omitempty"`
}

// Templates is an Array of Template structs.
Expand Down
95 changes: 95 additions & 0 deletions template_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package zabbix

// TemplateGroup represent Zabbix template group object, new in v6.2
// https://www.zabbix.com/documentation/6.2/en/manual/api/reference/templategroup/object
type TemplateGroup struct {
GroupID string `json:"groupid,omitempty"`
Name string `json:"name"`
}

// TemplateGroups is an array of TemplateGroup
type TemplateGroups []TemplateGroup

// TemplateGroupsGet Wrapper for templategroup.get
// https://www.zabbix.com/documentation/6.2/en/manual/api/reference/templategroup/get
func (api *API) TemplateGroupsGet(params Params) (res TemplateGroups, err error) {
if _, present := params["output"]; !present {
params["output"] = "extend"
}
err = api.CallWithErrorParse("templategroup.get", params, &res)
return
}

// TemplateGroupGetByID Gets host group by Id only if there is exactly 1 matching host group.
// https://www.zabbix.com/documentation/6.2/en/manual/api/reference/templategroup/get
func (api *API) TemplateGroupGetByID(id string) (res *TemplateGroup, err error) {
groups, err := api.TemplateGroupsGet(Params{"groupids": id})
if err != nil {
return
}

if len(groups) == 1 {
res = &groups[0]
} else {
e := ExpectedOneResult(len(groups))
err = &e
}
return
}

// TemplateGroupsCreate Wrapper for templategroup.create
// https://www.zabbix.com/documentation/6.2/en/manual/api/reference/templategroup/create
func (api *API) TemplateGroupsCreate(TemplateGroups TemplateGroups) (err error) {
response, err := api.CallWithError("templategroup.create", TemplateGroups)
if err != nil {
return
}

result := response.Result.(map[string]interface{})
groupids := result["groupids"].([]interface{})
for i, id := range groupids {
TemplateGroups[i].GroupID = id.(string)
}
return
}

// TemplateGroupsUpdate Wrapper for templategroup.update
// https://www.zabbix.com/documentation/6.2/en/manual/api/reference/templategroup/update
func (api *API) TemplateGroupsUpdate(TemplateGroups TemplateGroups) (err error) {
_, err = api.CallWithError("templategroup.update", TemplateGroups)
return
}

// TemplateGroupsDelete Wrapper for templategroup.delete
// Cleans GroupId in all TemplateGroups elements if call succeed.
// https://www.zabbix.com/documentation/6.2/en/manual/api/reference/templategroup/delete
func (api *API) TemplateGroupsDelete(TemplateGroups TemplateGroups) (err error) {
ids := make([]string, len(TemplateGroups))
for i, group := range TemplateGroups {
ids[i] = group.GroupID
}

err = api.TemplateGroupsDeleteByIds(ids)
if err == nil {
for i := range TemplateGroups {
TemplateGroups[i].GroupID = ""
}
}
return
}

// TemplateGroupsDeleteByIds Wrapper for templategroup.delete
// https://www.zabbix.com/documentation/6.2/en/manual/api/reference/templategroup/delete
func (api *API) TemplateGroupsDeleteByIds(ids []string) (err error) {
response, err := api.CallWithError("templategroup.delete", ids)
if err != nil {
return
}

result := response.Result.(map[string]interface{})
groupids := result["groupids"].([]interface{})
if len(ids) != len(groupids) {
err = &ExpectedMore{len(ids), len(groupids)}
}
return
}
Loading

0 comments on commit b0a7b3f

Please sign in to comment.