一、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)
}
七、总结:
当然这个模块里面还有很多方法,目前来说我们在做运维平台开发的时候差不多够用,像维护生命周期之类的大家可以去动手实际,接口还是写得非常清楚了