📜 ⬆️ ⬇️

Automating the addition of the server in Zabbix with the appointment of templates

The easiest way to add a new server to Zabbix is ​​through a web interface. They started a new server, went to the web-face, added a typewriter. But when something is done by hand, one can always forget, especially when putting servers into operation often.
After another such incident: something crashed, and then it turned out that it had never been monitored, the thought arose of automating the process.

The study showed that the server can be automatically added in several ways:

  1. Through network discovery - we set the address range, the system periodically launches a scan of the ports and, based on the results of the discovery, allows you to automatically add a node, as well as assign one or another template based on the received data.
    This option is not bad, but, in my case, there are a lot of subnets, they change, each time adding lists to zabbiks would be inconvenient. In addition, not all information about the system can be found by polling the ports.
  2. Auto Registration You can configure the zabbix server so that when you connect a new agent (determined by the unique host name), the host will be added to one or another group. Also, you can add a set of templates.
    In this case, we are moving away from scanning and address ranges, but we get a lack of flexibility in terms of patterns.
  3. There are options - to generate a template on the fly, write information directly to the database, etc. - everything is somehow difficult.

Since, during the setup of the new server, the agent config is generated automatically, using puppet, it was decided to use the second option - auto-registration, and then roll in the required templates via the zabbiks API.
In fact, the presence of the folder is not critical, you can throw the script on a new host in some other way and use something else to determine the parameters of the host configuration. I will give a simple option, but to think through to a more complex scheme is not difficult.

So, the algorithm is as follows:

  1. When setting up the server, a zabbix agent arrives at it, in the config of which the FQDN of the host name is written. Also, comes the zabbixapi.py script, which can work with the zabbix API.
  2. The agent is knocking on the server, auto registration is triggered, the host falls into a special AutoRegistered group, the “New Server” template is automatically applied to it, with a single data item host.relocate
  3. Zabbix server, polls the host.relocate key, which runs the zabbixapi.py script.
  4. The script, in turn, determines the basic parameters of the host, climbs through the API on Zabbix server, deletes the host from the AutoRegistered group there, deletes the New Server template, adds them to the necessary groups and includes the necessary templates.

Some complexity with an intermediate template is needed in order to get away from the unnecessary launch of zabbixapi.py. In fact, the zabbix server itself stops pulling it as soon as the host leaves the AutoRegistered group. In any other case, one would have to either run the script constantly with a certain periodicity, or run it once, without being able to verify the result.

What do we need to configure to make the whole system work?

  1. Create a group of network AutoRegister nodes on the Zabbix server
  2. Create an Autoregister template with a single data element.
    host.relocate
    image
  3. Create a discovery rule that assigns a new template to the new host and adds it to the AutoRegistered group. In the Web interface - Settings -> Actions, select at the top right - event source: Auto-registration -> New Action
    Host autoregistration
    image

    ')
  4. Add a corresponding UserParameter to the config of the zabbiks agent:
    UserParameter=host.relocate,/etc/zabbix/bin/zabbixapi.py > /dev/null 2>&1 ;echo $?
  5. Put the script on the specified path:
    /etc/zabbix/bin/zabbixapi.py
     #!/usr/bin/env python import urllib, json, httplib, socket, sys, os def httpRequest(request): body = json.dumps(request) headers = {"Content-type": "application/json"} conn = httplib.HTTPConnection("zabbix.example.com", 80) conn.request("POST", "/api_jsonrpc.php", body, headers) response = conn.getresponse() data = response.read() conn.close() return data me = os.popen('facter --puppet fqdn').read().strip('\n') #    authToken = httpRequest({"jsonrpc": "2.0","method":"user.authenticate","params":{"user":"API_USER","password":"API_PASSWORD"},"auth": None,"id":0}) authToken = json.loads(authToken).get('result', None) # ,      Autoregistered hostInGroup = httpRequest({"jsonrpc":"2.0","method":"host.get","params":{"output":"extend","filter":{"host":me}, "groupids":"21"},"auth":authToken,"id":1}) hostInGroup = json.loads(hostInGroup).get('result', None) if hostInGroup: hostID = httpRequest({"jsonrpc":"2.0","method":"host.get","params":{"output":"extend","filter":{"host":me}, "groupids":"21"},"auth":authToken,"id":2}) hostID = json.loads(hostID) hostID = hostID['result'][0]['hostid'] print "Host is in AutoRegistered Group" print "HostID is",hostID print "We need to update host info, link templates and move host to proper group" #  facter  ,      print "Collecitng host info..." osFamily = os.popen('facter --puppet kernel').read().strip('\n') virtualEnv = os.popen('facter --puppet virtual').read().strip('\n') print "Base OS is",osFamily if osFamily == "FreeBSD": hostGroups = [{"groupid":"11"}, {"groupid":"6"}] hostTemplates = [{"templateid":"10077"}, {"templateid":"10090"}] if osFamily == "Linux": print "Checking virtualization..." if virtualEnv == "physical": print "Physical host detected, no virtualization" hostGroups = [{"groupid":"11"}, {"groupid":"2"}] hostTemplates = [{"templateid":"10076"}, {"templateid":"10090"}, {"templateid":"10127"}] if virtualEnv == "openvzve" or virtualEnv == "openvz": print "OpenVZ virtualization detected" hostGroups = [{"groupid":"11"}, {"groupid":"14"}] hostTemplates = [{"templateid":"10117"}, {"templateid":"10090"}] print "Detected groups are", hostGroups print "Detected templates are", hostTemplates updateHost = { "jsonrpc":"2.0", "method":"host.update", "params":{ "hostid":hostID, "ip":"127.0.0.1", "groups":hostGroups, "templates":hostTemplates, "templates_clear":"10263" }, "auth":authToken, "id":3 } print "Trying to update host..." httpRequest(updateHost) hostInterfaceID = httpRequest({"jsonrpc":"2.0","method":"hostinterface.get","params":{"output":"extend", "hostids":hostID},"auth":authToken,"id":4}) hostInterfaceID = json.loads(hostInterfaceID) hostInterfaceID = hostInterfaceID['result'][0]['interfaceid'] print "Host Interface ID detected as", hostInterfaceID updateHostInterface = { "jsonrpc":"2.0", "method":"hostinterface.update", "params":{ "interfaceid":hostInterfaceID, "dns": me, "useip": 0 }, "auth":authToken, "id":4 } print "Trying to update host interface to DNS based..." httpRequest(updateHostInterface) sys.exit(0) else: print "Host is absent in AutoRegistered Group" print "Nothing to do..." sys.exit(0) 


    In the example above, we are looking at the operating system: Linux or FreeBSD, we are looking at the availability of OpenVZ virtualization - this affects the choice of basic templates. If necessary, the functionality is easy to expand, I publish a simple version moznatno, since the implementation may be very different from what we use.
    Attention, in the script the numbers of groups and templates are hard-coded, they will be different in your installation, do not forget to correct it!

Source: https://habr.com/ru/post/211384/


All Articles