go 利用zabbix API进行管理
  DMGk6WNJGqlo 2023年11月19日 37 0

一、go编程

   之前工作原因都在使用python进行zabbix 的相关开发,使用python的朋友可以看我之前写的这篇:https://blog.51cto.com/xiaoluoge/1827151 。最近由于接触了相关go的开发环境,所以想使用go对之前编写的运维监控平台进行重构(这个也是学习一门编程语言的重要手段,硬着头皮实现对应功能。就初步掌握了),所以就有了对应的相关文章:


二、环境说明:

zabbix:6.0 (版本兼容)

开发工具:goland

go版本:1.20

三、手动进行go 获取所有主机信息

1、使用原生接口和zabbix对应token生成,可以在zabbix内部生成:

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
)

func PostRequest(payload string, url string) {
	method := "POST"
	pl := strings.NewReader(payload)
	client := &http.Client{}
	req, err := http.NewRequest(method, url, pl)

	if err != nil {
		fmt.Println(err)
		return
	}
	req.Header.Add("Content-Type", "application/json")

	res, err := client.Do(req)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer res.Body.Close()

	body, err := ioutil.ReadAll(res.Body)

	if err != nil {
		log.Println(err)
		return
	}
	fmt.Println(string(body))
}

func main() {
	const api = "http://10.10.1.113:30331/api_jsonrpc.php"
	const token = "c79e921dbb02ce1fa74f9e01bc68a97415f596af5626fcfa0bee8399b01ad5d6"

	a := fmt.Sprintf(`{
		"jsonrpc": "2.0",
		"method": "host.get",
		"params": {"output": "extend"},
		"auth": "%s","id": 2
		}`, token)

	PostRequest(a, api)
}

2、执行代码返回结果

{"jsonrpc":"2.0","result":[{"hostid":"10084","proxy_hostid":"0","host":"Zabbix s
erver","status":"0","lastaccess":"0","ipmi_authtype":"-1","ipmi_privilege":"2","
ipmi_username":"","ipmi_password":"","maintenanceid":"0","maintenance_status":"0
","maintenance_type":"0","maintenance_from":"0","name":"Zabbix server","flags":"
0","templateid":"0","description":"","tls_connect":"1","tls_accept":"1","tls_iss
uer":"","tls_subject":"","proxy_address":"","auto_compress":"1","custom_interfac
es":"0","uuid":"","inventory_mode":"-1"},{"hostid":"10529","proxy_hostid":"0","h
ost":"10.2.4.12","status":"0","lastaccess":"0","ipmi_authtype":"-1","ipmi_privil
ege":"2","ipmi_username":"","ipmi_password":"","maintenanceid":"0","maintenance_
status":"0","maintenance_type":"0","maintenance_from":"0","name":"10.2.4.12","fl
ags":"0","templateid":"0","description":"","tls_connect":"1","tls_accept":"1","t
ls_issuer":"","tls_subject":"","proxy_address":"","auto_compress":"1","custom_in
terfaces":"0","uuid":"","inventory_mode":"-1"}],"id":2}

我们可以看到返回了这样一串json数据:

{"jsonrpc":"2.0","result":[{}],"id":2}

四、改造json结果,使得返回的结果变成结构体:

1、通常在我们go里面,我们要把返回的数据统一形成结构体,当有调用的时候通过结构体转换json数据到前端即可,所以我们对以上返回结果进行定义:

type resultInfo struct {
	Hostid string `json:"hostid"`
	Status string `json:"status"`
	Name   string `json:"name"`
}

type ret []resultInfo

type Response struct {
	Jsonrpc string `json:"jsonrpc"`
	Result  ret    `json:result`
	Id      int    `json:"id"`
}

Response定义了返回的方法,然后嵌套了上层resultInfo的结构体。结果里面我们只要返回hostid,status,name三个字段,当然也可以返回多个字段:

2、最终修改后的代码

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
)

type resultInfo struct {
	Hostid string `json:"hostid"`
	Status string `json:"status"`
	Name   string `json:"name"`
}

type ret []resultInfo

type Response struct {
	Jsonrpc string `json:"jsonrpc"`
	Result  ret    `json:result`
	Id      int    `json:"id"`
}

type Byte []byte


func PostRequest(payload string, url string) (ret Byte) {
	method := "POST"
	pl := strings.NewReader(payload)
	client := &http.Client{}
	req, err := http.NewRequest(method, url, pl)

	if err != nil {
		fmt.Println(err)
		return
	}
	req.Header.Add("Content-Type", "application/json")

	res, err := client.Do(req)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer res.Body.Close()

	body, err := ioutil.ReadAll(res.Body)

	if err != nil {
		log.Println(err)
		return
	}
	return body
}

func main() {
	const api = "http://10.10.1.113:30331/api_jsonrpc.php"
	const token = "c79e921dbb02ce1fa74f9e01bc68a97415f596af5626fcfa0bee8399b01ad5d6"

	a := fmt.Sprintf(`{
		"jsonrpc": "2.0",
		"method": "host.get",
		"params": {"output": "extend"},
		"auth": "%s","id": 2
		}`, token)

	ret := PostRequest(a, api)
	var response Response
	json.Unmarshal([]byte(ret), &response)
	fmt.Println(response.Result)
}

执行之后返回结果:

[{10084 0 Zabbix server} {10529 0 10.2.4.12}]

3、我们可以遍历返回的结果:

	json.Unmarshal([]byte(ret), &response)
	for _, Data := range response.Result {
		fmt.Println("hostid", Data.Hostid, "Status", Data.Status, "Name", Data.Name)
	}

执行之后返回结果:

hostid 10084 Status 0 Name Zabbix server
hostid 10529 Status 0 Name 10.2.4.12

可以看到从我一个python开发者角度来说还是非常复杂,当然也有很多网上已经写好的接口github模块的地址为:

github.com/claranet/go-zabbix-api

五、安装对应模块可以使用

go get github.com/claranet/go-zabbix-api

六、模块使用:

1、获取对应主机信息:

package main

import (
	"fmt"
	"github.com/claranet/go-zabbix-api"
)

func main() {
	user := "Admin"
	pass := "zabbix"
	api := zabbix.NewAPI("http://10.10.1.113:30331/api_jsonrpc.php")
	api.Login(user, pass)

	res, _ := api.HostsGet(zabbix.Params{"output": "extend"})
	for _, server := range res {
		fmt.Println("Name:", server.Name, "ID:", server.HostID)
	}

	fmt.Println(res)
}

返回结果:

Name: Zabbix server ID: 10084
Name: 10.2.4.12 ID: 10529

2、获取所有主机组信息:

package main

import (
	"fmt"
	"github.com/claranet/go-zabbix-api"
)

func main() {
	user := "Admin"
	pass := "zabbix"
	api := zabbix.NewAPI("http://10.10.1.113:30331/api_jsonrpc.php")
	api.Login(user, pass)

	res, _ := api.HostGroupsGet(zabbix.Params{"output": "extend"})
	for _, server := range res {
		fmt.Println("Name:", server.Name, "ID:", server.GroupID)
	}

	fmt.Println(res)
}

返回结果:

Name: Templates ID: 1
Name: Linux servers ID: 2
Name: Zabbix servers ID: 4
Name: Discovered hosts ID: 5
Name: Virtual machines ID: 6
Name: Hypervisors ID: 7
Name: Templates/Modules ID: 8
Name: Templates/Network devices ID: 9   
Name: Templates/Operating systems ID: 10
Name: Templates/Server hardware ID: 11  
Name: Templates/Applications ID: 12     
Name: Templates/Databases ID: 13        
Name: Templates/Virtualization ID: 14   
Name: Templates/Telephony ID: 15        
Name: Templates/SAN ID: 16
Name: Templates/Video surveillance ID: 17
Name: Templates/Power ID: 18

3、通过主机组获取主机信息

package main

import (
	"fmt"
	"github.com/claranet/go-zabbix-api"
)

func main() {
	user := "Admin"
	pass := "zabbix"
	api := zabbix.NewAPI("http://10.10.1.113:30331/api_jsonrpc.php")
	api.Login(user, pass)

	res, _ := api.HostsGetByHostGroupIds([]string{"2", "4"})
	for _, server := range res {
		fmt.Println("Name:", server.Name, "ID:", server.HostID)
	}

	fmt.Println(res)
}

返回结果:

Name: Zabbix server ID: 10084
Name: 10.2.4.12 ID: 10529

4、创建主机并关联主机组:

package main

import (
	"fmt"
	"github.com/claranet/go-zabbix-api"
)

func main() {
	user := "Admin"
	pass := "zabbix"
	api := zabbix.NewAPI("http://10.10.1.113:30331/api_jsonrpc.php")
	api.Login(user, pass)

	// Host Interface
	i := zabbix.HostInterface{DNS: "",
		IP:    "192.168.1.1",
		Main:  1,
		Port:  "10050",
		Type:  1,
		UseIP: 1}

	interfaces := zabbix.HostInterfaces{i}

	// group id
	g := zabbix.HostGroupID{GroupID: "2"}
	groups := zabbix.HostGroupIDs{g}

	// Host
	h := zabbix.Host{Host: "Super Server",
		Available:  1,
		GroupIds:   groups,
		Name:       "Super Server",
		Status:     0,
		Interfaces: interfaces}

	hosts := zabbix.Hosts{h}
	res := api.HostsCreate(hosts)
	fmt.Println(res)
}

5、创建主机并且关联模板:

package main

import (
	"fmt"
	"github.com/claranet/go-zabbix-api"
)

func main() {
	user := "Admin"
	pass := "zabbix"
	api := zabbix.NewAPI("http://10.10.1.113:30331/api_jsonrpc.php")
	api.Login(user, pass)

	// Host Interface
	type HostTemplate struct {
		TemplateId string `json:"templateid"`
	}

	type Templates []HostTemplate

	t := HostTemplate{TemplateId: "10001"}
	templates := Templates{t}

	// host interface
	i := zabbix.HostInterface{DNS: "",
		IP:    "192.168.0.90",
		Main:  1,
		Port:  "10050",
		Type:  1,
		UseIP: 1}

	interfaces := zabbix.HostInterfaces{i}

	// group id
	g := zabbix.HostGroupID{GroupID: "2"}
	groups := zabbix.HostGroupIDs{g}

	res, _ := api.Call("host.create", zabbix.Params{"host": "Super Server",
		"interfaces": interfaces,
		"groups":     groups,
		"templates":  templates})
	fmt.Println(res)

}

七、总结:

   当然这个模块里面还有很多方法,目前来说我们在做运维平台开发的时候差不多够用,像维护生命周期之类的大家可以去动手实际,接口还是写得非常清楚了

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月19日 0

暂无评论

推荐阅读
  MHUUsenkOJj9   2023年11月24日   29   0   0 Dockergithub
  hs9CtFCuSvuL   2023年11月19日   27   0   0 DatabaseHCLjson