488 lines
18 KiB
Go
488 lines
18 KiB
Go
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)
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
}
|