Ad Widget

Collapse

Updating images using the API via configuration.import

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • rtravis
    Junior Member
    • Nov 2013
    • 8

    #1

    Updating images using the API via configuration.import

    Hi

    I'm using zabbix 2.4.0 with postgreSQL as a back end running on RHEL6. I'm having an issue while trying to use the API to import images. I've got an xml file from an export that has an image in it. For a fresh install, I can use the API to create the image initially. If I try to run the same exact import a second time, I get the following error:

    {u'error': {u'code': -32500, u'data': u'', u'message': u'Application error.'},
    u'id': 2,
    u'jsonrpc': u'2.0'}

    Not very useful since the data value is empty. When I try to import through the GUI, it works fine. Here is the python script I'm using for import:

    Code:
    import os
    import sys
    import urllib2
    import hashlib
    try:
        import json
    except ImportError:
        import simplejson as json
    
    from pprint import pprint
    
    url     = "http://zabbix/zabbix/api_jsonrpc.php"
    usr     = "Admin"
    passwrd = "zabbix"
    
    hash_pass = ""
    
    def zbxAuth():
       global hash_pass
       login = {
          "jsonrpc" : "2.0",
          "method"  : "user.login",
          "params"  : {
             "user"     : usr,
             "password" : passwrd
          },
          "id"     : 1
       }
       res = printResult(login)
    
       if 'error' in res:
          print "Error: Connection Unsuccessful"
          sys.exit(-1)
       hash_pass=res["result"]
       print "Successfully Authenticated. Auth ID: " + hash_pass
    
    
    def zbxImport(filename):
       global hash_pass
       try:
          file = open(filename, 'rb')
       except:
          sys.exit("Error.  Could not open file " + filename)
    
       imprt = {
          "jsonrpc": "2.0",
          "method" : "configuration.import",
          "params" : {
             "format"    :   "xml",
             "rules"     :   {
                "images"     :   {
                      "createMissing"   :  True,
                      "updateExisting"  :  True
                }
              },
              "source" :  file.read()
           },
           "auth" : hash_pass,
           "id"   : 2
       }
    
       file.close()
    
       res = printResult(imprt)
       if 'error' in res:
           print "Import unsuccessful for file: " + str(filename)
           print str(pprint(res))
           sys.exit(-1)
    
    
    
    def printResult(var):
       data = json.dumps(var)
       request = urllib2.Request(url, data, {"Content-Type" : "application/json"})
       response = urllib2.urlopen(request)
       return json.load(response)
    
    if __name__ == "__main__":
    
       if len (sys.argv) != 2:
          sys.exit("Usage: " + sys.argv[0] + " [filename.xml]")
    
       zbxAuth()
       zbxImport(sys.argv[1])
    If I change the rules to templates or hosts and chose a file containing those types, I can reimport just fine. Just not for the images.

    Not sure if this is a bug, or me being an idiot.
  • rtravis
    Junior Member
    • Nov 2013
    • 8

    #2
    After much time in the code...

    So I think the problem is half me being an idiot and half a bug. Basically, if the createMissing flag is set to true, but there are no new images in the import, the import fails. The api code looks like this:

    /include/classes/import/CConfigurationImport.php

    PHP Code:
            protected function processImages() {
                    if (
    CWebUser::$data['type'] != USER_TYPE_SUPER_ADMIN
                                    
    || (!$this->options['images']['updateExisting'] && !$this->options['images']['createMissing'])) {
                            return;
                    }

                    
    $allImages $this->getFormattedImages();

                    if (!
    $allImages) {
                            return;
                    }

                    
    $imagesToUpdate = array();
                    
    $allImages zbx_toHash($allImages'name');

                    
    $dbImages DBselect('SELECT i.imageid,i.name FROM images i WHERE '.dbConditionString('i.name'array_keys($allImages)));
                    while (
    $dbImage DBfetch($dbImages)) {
                            
    $dbImage['image'] = $allImages[$dbImage['name']]['image'];
                            
    $imagesToUpdate[] = $dbImage;
                            unset(
    $allImages[$dbImage['name']]);
                    }

                    if (
    $this->options['images']['createMissing']) {
                            
    API::Image()->create(array_values($allImages));
                    }

                    if (
    $this->options['images']['updateExisting']) {
                            
    API::Image()->update($imagesToUpdate);
                    }
            } 
    In the while loop, it unsets all images in the allImages array that are already in the database. When it runs API::Image()->create(array_values($allImages)); the array is empty and the validator does not like that. I don't want to dynamically determine beforehand whether or not to set the createMissing flag, so I changed the code to be
    PHP Code:
                    if ($this->options['images']['createMissing'] && sizeof($allImages) != 0) {
                            
    API::Image()->create(array_values($allImages));
                    } 
    Hope this helps someone.

    Comment

    Working...