glpi-go/zabbix2glpi/zabbix2glpi.go

488 lines
18 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package main
import (
"encoding/json"
"flag"
"fmt"
"glpi"
"os"
"strings"
"zabbix"
)
// Find and return a single host object by name
func GetHost(zabbixAPI *zabbix.API, host string) (zabbix.ZabbixHost, error) {
params := make(map[string]interface{}, 0)
filter := make(map[string]string, 0)
filter["host"] = host
params["filter"] = filter
params["output"] = "extend"
params["select_groups"] = "extend"
params["templated_hosts"] = 1
params["selectInventory"] = "extend"
params["selectInterfaces"] = "extend"
ret, err := zabbixAPI.Host("get", params)
// This happens if there was an RPC error
if err != nil {
return nil, err
}
// If our call was successful
if len(ret) > 0 {
return ret[0], err
}
// This will be the case if the RPC call was successful, but
// Zabbix had an issue with the data we passed.
return nil, &zabbix.ZabbixError{0, "", "Host not found"}
}
func GetHostGroup(zabbixAPI *zabbix.API, hostgroup string, select_type string) (zabbix.ZabbixHostGroup, error) {
params := make(map[string]interface{}, 0)
filter := make(map[string]string, 0)
filter["name"] = hostgroup
params["filter"] = filter
params["output"] = "extend"
if select_type == "all_hosts" {
params["selectHosts"] = "extend"
}
// params["select_groups"] = "extend"
//params["templated_hosts"] = 1
ret, err := zabbixAPI.HostGroup("get", params)
if err != nil {
return nil, err
}
// If our call was successful
if len(ret) > 0 {
return ret[0], err
}
// This will be the case if the RPC call was successful, but
// Zabbix had an issue with the data we passed.
return nil, &zabbix.ZabbixError{0, "", "HostGroup not found"}
}
func MigrateHost(glpiAPI *glpi.Session, zabbixAPI *zabbix.API, item interface{}, glpiLocationID int) {
var (
zbxHostOS string
zbxHostIP string
zbxHostFQDN string
zbxHostSerial string
zbxHostOtherSerial string
zbxHostUseDate string
zbxHostManufacturer string
zbxHostComputerModel string
glpiItemStatusID int
)
itemType := "Computer"
typeID := glpiAPI.SearchItem("ComputerType", "Сервер")
// location_id := glpiAPI.SearchItem("Location", "ГО")
fmt.Println(typeID)
// Получаем имя узла, id и флаг инвентаризации
zbxHostName := fmt.Sprint(item.(map[string]interface{})["host"])
zbxHostStatus := fmt.Sprint(item.(map[string]interface{})["status"])
// // если "inventory_mode": "-1" то инвентаризация отключена
zbxHostHasInventory := fmt.Sprint(item.(map[string]interface{})["inventory_mode"])
// Если имя узла в заббикс как FQDN то обрезаем до первой точки
// zbxHostName_short := strings.Split(zbxHostName, ".")[0]
glpiCompID := glpiAPI.SearchItem("Computer", strings.ToLower(zbxHostName))
fmt.Println(">>>>>>> ", zbxHostName)
if glpiCompID != 0 {
fmt.Println("Узел ", zbxHostName, " существует в glpi c id:", glpiCompID)
return
}
// По имени узла запрашиваем полную информацию из заббикса и выдергиваем данные
zbxHostInfo, _ := GetHost(zabbixAPI, fmt.Sprint(zbxHostName))
for _, i := range zbxHostInfo["interfaces"].([]interface{}) {
zbxHostIP = fmt.Sprint(i.(map[string]interface{})["ip"])
zbxHostFQDN = strings.ToLower(fmt.Sprint(i.(map[string]interface{})["dns"]))
fmt.Println(zbxHostIP, zbxHostFQDN)
}
// Проверяем если флаг инвентаризации не равен -1 то получаем инвентарные данные
if zbxHostHasInventory != "-1" {
zbxHostOS = fmt.Sprint(zbxHostInfo["inventory"].(map[string]interface{})["os"])
zbxHostSerial = fmt.Sprint(zbxHostInfo["inventory"].(map[string]interface{})["serialno_a"])
zbxHostOtherSerial = fmt.Sprint(zbxHostInfo["inventory"].(map[string]interface{})["serialno_b"])
zbxHostUseDate = fmt.Sprint(zbxHostInfo["inventory"].(map[string]interface{})["date_hw_install"])
zbxHostManufacturer = fmt.Sprint(zbxHostInfo["inventory"].(map[string]interface{})["vendor"])
zbxHostComputerModel = fmt.Sprint(zbxHostInfo["inventory"].(map[string]interface{})["model"])
fmt.Println(zbxHostOS, zbxHostSerial, zbxHostOtherSerial, zbxHostUseDate, zbxHostManufacturer, zbxHostComputerModel)
}
// получаем id модели оборудования. Если не найдено добавляем в glpi
glpiModelID := glpiAPI.SearchItem("ComputerModel", zbxHostComputerModel)
if glpiModelID == 0 {
requestData := glpi.GlpiComputerModel{
Name: zbxHostComputerModel,
}
glpiModelID = glpiAPI.ItemOperation("add", "ComputerModel", requestData)
}
// получаем id производителя из glpiAPI. если нету добавляем
glpiManufacturerID := glpiAPI.SearchItem("Manufacturer", zbxHostManufacturer)
if glpiManufacturerID == 0 {
requestData := glpi.GlpiManufacturer{
Name: zbxHostManufacturer,
}
glpiManufacturerID = glpiAPI.ItemOperation("add", "Manufacturer", requestData)
}
// добавляем железку
// проверяем статус
if zbxHostStatus == "0" {
glpiItemStatusID = glpiAPI.SearchItem("State", "В работе")
}
if zbxHostStatus == "1" {
glpiItemStatusID = glpiAPI.SearchItem("State", "Выключено")
}
requestDataComp := glpi.GlpiComputer{
Name: strings.ToLower(zbxHostName),
Serial: zbxHostSerial,
Otherserial: zbxHostOtherSerial,
Locations_id: glpiLocationID,
Computermodels_id: glpiModelID,
Computertypes_id: typeID,
Manufacturers_id: glpiManufacturerID,
States_id: glpiItemStatusID,
}
glpiCompID = glpiAPI.ItemOperation("add", "Computer", requestDataComp)
fmt.Println("Добавлен хост", glpiCompID)
// Если выставлена дата установки то включаем фин. информаци.
// к году прибвавляем месяц и день
if len(zbxHostUseDate) <= 4 {
zbxHostUseDate = zbxHostUseDate + "-01-01"
}
if zbxHostUseDate != "" {
requestDataInfocom := glpi.GlpiInfocom{
Items_id: glpiCompID,
Itemtype: itemType,
Use_date: zbxHostUseDate,
}
// fmt.Println("--->", requestDataInfocom)
glpiAPI.ItemOperation("add", "InfoCom", requestDataInfocom)
fmt.Println("Добавлена фин. информация ", glpiCompID)
}
// Добавляем сетевой порт, адрес, FQDN, e.t.c
if zbxHostIP != "" {
glpiNetworkPortData := glpi.GlpiNetworkPort{
Items_id: glpiCompID,
Itemtype: itemType,
Name: "Eth",
Instantiation_type: "NetworkPortEthernet",
}
glpiPortID := glpiAPI.ItemOperation("add", "NetworkPort", glpiNetworkPortData)
fmt.Println("Добавлен port", glpiPortID)
// Отделяем имя узла от домена
zbxHostFQDN_short := strings.Split(zbxHostFQDN, ".")[0]
prefix := zbxHostFQDN_short + "."
zbxHostDomain := strings.TrimLeft(zbxHostFQDN, prefix)
fmt.Println(zbxHostFQDN, zbxHostFQDN_short, zbxHostDomain)
// Определяем ID домена в GLPI если он там есть
glpiFqdnID := glpiAPI.SearchItem("FQDN", zbxHostDomain)
fmt.Println("Домен - ", zbxHostDomain, glpiFqdnID)
glpiNetworkData := glpi.GlpiNetworkName{
Items_id: glpiPortID,
Itemtype: "NetworkPort",
Name: zbxHostFQDN_short,
Fqdns_id: glpiFqdnID,
}
glpiNetworkID := glpiAPI.ItemOperation("add", "NetworkName", glpiNetworkData)
fmt.Println("Добавлена сеть", glpiNetworkID)
glpiIPAdressData := glpi.GlpiIPAddress{
Items_id: glpiNetworkID,
Itemtype: "NetworkName",
Name: zbxHostIP,
}
glpiIpAddressID := glpiAPI.ItemOperation("add", "IPAddress", glpiIPAdressData)
fmt.Println("Добавлен IP", glpiIpAddressID)
}
// Проверяем что в заббикс для узла есть запись об ОС
if zbxHostOS != "" {
// получаем id ОС из glpiAPI. если нет добавляем
glpiOSID := glpiAPI.SearchItem("OperatingSystem", zbxHostOS)
fmt.Println("Добавлена ОС", glpiOSID)
if glpiOSID == 0 {
// request_data_os := glpi.GlpiOperatingSystem{
// Name: zbxHostOS,
// }
glpiOSID = glpiAPI.ItemOperation("add", "OperatingSystem", glpi.GlpiOperatingSystem{Name: zbxHostOS})
fmt.Println("Добавлена ОС", glpiOSID)
}
// Привязываем ОС к узлу в GLPI
requestDataOSItem := glpi.GlpiOSItem{
Items_id: glpiCompID,
Itemtype: itemType,
Operatingsystems_id: glpiOSID,
}
glpiAPI.ItemOperation("add", "Item_OperatingSystem", requestDataOSItem)
}
}
func UpdateHostStatus(glpiAPI *glpi.Session, zabbixAPI *zabbix.API, item interface{}) {
// Получаем имя узла, id и флаг инвентаризации
itemType := "Computer"
// typeID := glpiAPI.SearchItem("ComputerType", "Сервер")
zbxHostName := fmt.Sprint(item.(map[string]interface{})["host"])
zbxHostStatus := fmt.Sprint(item.(map[string]interface{})["status"])
glpiItemID := glpiAPI.SearchItem(itemType, strings.ToLower(zbxHostName))
res := glpiAPI.GetItem(itemType, glpiItemID, "")
var statusInfo map[string]interface{}
err := json.Unmarshal(res, &statusInfo)
if err != nil {
fmt.Println(err)
}
glpiItemStatusID := statusInfo["states_id"]
fmt.Println(">>>>>>> ", zbxHostName, zbxHostStatus, "glp id:", glpiItemID, "glpi status", glpiItemStatusID)
var glpiStatusID int
if zbxHostStatus == "0" {
glpiStatusID = glpiAPI.SearchItem("State", "В работе")
}
if zbxHostStatus == "1" {
glpiStatusID = glpiAPI.SearchItem("State", "Выключено")
}
fmt.Println(glpiItemStatusID, glpiStatusID)
if glpiItemStatusID != glpiStatusID {
fmt.Println("Update")
glpiAPI.UpdateItemStatus(itemType, glpiItemID, glpiStatusID)
}
}
func main() {
var (
zabbixServerAPI string
zabbixUser string
zabbixPassword string
zabbixHost string
zabbixHostGroups string
operation string
outputFormat string
glpiServerAPI string
glpiUserToken string
glpiAppToken string
glpiLocationID int
)
flag.StringVar(&zabbixServerAPI, "zabbix-server-api", "", "zabbix server API URL. ZABBIX_SERVER_API")
flag.StringVar(&zabbixUser, "zabbix-user", "", "Zabbix user name. ZABBIX_USER")
flag.StringVar(&zabbixPassword, "zabbix-password", "", "Zabbix password. ZABBIX_PASSWORD")
flag.StringVar(&zabbixHost, "zabbix-host", "", "Zabbix host name")
flag.StringVar(&zabbixHostGroups, "zabbix-host-groups", "", "Zabbix host groups, can be comma-separated list")
flag.StringVar(&glpiServerAPI, "glpi-server-api", "", "Glpi instance API URL. GLPI_SERVER_URL")
flag.StringVar(&glpiUserToken, "glpi-user-token", "", "Glpi user API token. GLPI_USER_TOKEN")
flag.StringVar(&glpiAppToken, "glpi-app-token", "", "Glpi aplication API token. GLPI_APP_TOKEN")
flag.IntVar(&glpiLocationID, "glpi-location-id", 0, "Glpi location id for migration hosts")
flag.StringVar(&operation, "operation", "zabbix-version", "Opertation type, must be:\n\tzabbix-version\n\tglpi-version\n\tget-host - getting zabbix host information\n\tget-hostgroup - getting zabbix hosts group\n\tget-hosts-from-group - getting zabbix group members hosts\n\tmigrate-host - migrate host from Zabbix to GLPI\n\tmigrate-hosts-from-group - migrate all zabbix groups members hosts to GLPI\n\tupdate-host-status - get host status from zabbix and update them into zabbix\n\tupdate-hosts-status-from-group - get group members hosts status from zabbix and update into glpi\n\t")
flag.StringVar(&outputFormat, "output-format", "go", "Output format: 'go' - go map, 'json' - json string")
flag.Parse()
if zabbixServerAPI == "" && os.Getenv("ZABBIX_SERVER_API") == "" {
fmt.Println("Send error: make sure environment variables `ZABBIX_SERVER_API`, or used with '-zabbix-server-api' argument")
os.Exit(1)
} else if zabbixServerAPI == "" && os.Getenv("ZABBIX_SERVER_API") != "" {
zabbixServerAPI = os.Getenv("ZABBIX_SERVER_API")
}
// fmt.Println(zabbixServerAPI)
if zabbixUser == "" && os.Getenv("ZABBIX_USER") == "" {
fmt.Println("Send error: make sure environment variables `ZABBIX_USER`, or used with '-zabbix-user' argument")
os.Exit(1)
} else if zabbixUser == "" && os.Getenv("ZABBIX_USER") != "" {
zabbixUser = os.Getenv("ZABBIX_USER")
}
// fmt.Println(zabbixUser )
if zabbixPassword == "" && os.Getenv("ZABBIX_PASSWORD") == "" {
fmt.Println("Send error: make sure environment variables `ZABBIX_PASSWORD`, or used with '-zabbix-password' argument")
os.Exit(1)
} else if zabbixPassword == "" && os.Getenv("ZABBIX_PASSWORD") != "" {
zabbixPassword = os.Getenv("ZABBIX_PASSWORD")
}
// fmt.Println(zabbixPassword)
//-----------------------------------------------------------
if glpiServerAPI == "" && os.Getenv("GLPI_SERVER_API") == "" {
fmt.Println("Send error: make sure environment variables `GLPI_SERVER_API`, or used with '-glpi-server-api' argument")
os.Exit(1)
} else if glpiServerAPI == "" && os.Getenv("GLPI_SERVER_API") != "" {
glpiServerAPI = os.Getenv("GLPI_SERVER_API")
}
if glpiUserToken == "" && os.Getenv("GLPI_USER_TOKEN") == "" {
fmt.Println("Send error: make sure environment variables `GLPI_USER_TOKEN`, or used with '-glpi-user-token' argument")
os.Exit(1)
} else if glpiUserToken == "" && os.Getenv("GLPI_USER_TOKEN") != "" {
glpiUserToken = os.Getenv("GLPI_USER_TOKEN")
}
if glpiAppToken == "" && os.Getenv("GLPI_APP_TOKEN") == "" {
fmt.Println("Send error: make sure environment variables `GLPI_APP_TOKEN`, or used with '-glpi-app-token' argument")
os.Exit(1)
} else if glpiAppToken == "" && os.Getenv("GLPI_APP_TOKEN") != "" {
glpiAppToken = os.Getenv("GLPI_APP_TOKEN")
}
// ------- Connected to zabbix API ----------
zabbixAPI, err := zabbix.NewAPI(zabbixServerAPI, zabbixUser, zabbixPassword)
if err != nil {
fmt.Println(err)
return
}
if operation != "zabbix-version" {
_, err = zabbixAPI.Login()
if err != nil {
fmt.Println(err)
return
}
// fmt.Println("Connected to API: OK")
}
// ------- Connected to GLPI API -----------
glpiAPI, err := glpi.NewSession(glpiServerAPI, glpiUserToken, glpiAppToken)
if err != nil {
fmt.Println(err)
return
}
_, err = glpiAPI.InitSession()
if err != nil {
fmt.Println(err)
return
}
switch operation {
case "zabbix-version":
zabbixVersion, err := zabbixAPI.Version()
if err != nil {
fmt.Println(err)
}
fmt.Println("Zabbix version:", zabbixVersion)
case "glpi-version":
glpiVersion := glpiAPI.Version()
fmt.Println("GLPI version:", glpiVersion)
case "get-host":
if zabbixHost == "" {
fmt.Println("Zabbix host not setting, using '-zabbix-host' command line argument")
os.Exit(1)
} else {
res, err := GetHost(zabbixAPI, zabbixHost)
if err != nil {
fmt.Println(err)
}
if outputFormat == "json" {
result, err := json.Marshal(res)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(result))
} else {
fmt.Println(res)
}
}
case "get-hostgroup":
if zabbixHostGroups == "" {
fmt.Println("Zabbix host group not setting, using '-zabbix-host-groups' command line argument")
os.Exit(1)
} else {
groupList := strings.Split(zabbixHostGroups, ",")
for _, item := range groupList {
fmt.Println(GetHostGroup(zabbixAPI, strings.TrimSpace(item), "no_host"))
}
}
case "get-hosts-from-group":
if zabbixHostGroups == "" {
fmt.Println("Zabbix host group not setting, using '-zabbix-host-groups' command line argument and comma separated list of groups into qoute")
os.Exit(1)
} else {
groupList := strings.Split(zabbixHostGroups, ",")
for _, item := range groupList {
res, err1 := GetHostGroup(zabbixAPI, strings.TrimSpace(item), "all_hosts")
// println(strings.TrimSpace(item))
if err1 != nil {
fmt.Println(err1)
}
if outputFormat == "json" {
result, err := json.Marshal(res)
if err != nil {
fmt.Println(err)
}
// если "inventory_mode": "-1" то инвентаризация отключена
fmt.Println(string(result))
} else {
fmt.Println(res)
}
}
}
case "migrate-host":
fmt.Println("Function not implemented yet")
case "migrate-hosts-from-group":
if zabbixHostGroups == "" {
fmt.Println("Zabbix host group not setting, using '-zabbix-host-groups' command line argument and comma separated list of groups into qoute")
os.Exit(1)
} else {
groupList := strings.Split(zabbixHostGroups, ",")
for _, item := range groupList {
res, err1 := GetHostGroup(zabbixAPI, strings.TrimSpace(item), "all_hosts")
println(strings.TrimSpace(item))
if err1 != nil {
fmt.Println(err1)
}
// Пробегаемся по массиву узлов из забикса и выдергиваем интерфейсы и инвентарные данные
for _, item := range res["hosts"].([]interface{}) {
MigrateHost(glpiAPI, zabbixAPI, item, glpiLocationID)
}
}
}
case "update-host-status":
fmt.Println("Function not implemented yet")
case "update-hosts-status-from-group":
if zabbixHostGroups == "" {
fmt.Println("Zabbix host group not setting, using '-zabbix-host-groups' command line argument and comma separated list of groups into qoute")
os.Exit(1)
} else {
groupList := strings.Split(zabbixHostGroups, ",")
for _, item := range groupList {
res, err1 := GetHostGroup(zabbixAPI, strings.TrimSpace(item), "all_hosts")
println(strings.TrimSpace(item))
if err1 != nil {
fmt.Println(err1)
}
// Пробегаемся по массиву узлов из забикса и выдергиваем статус
for _, item := range res["hosts"].([]interface{}) {
fmt.Println(item)
UpdateHostStatus(glpiAPI, zabbixAPI, item)
}
}
}
}
}