Infoblox Exchange Cybersecurity Roadshow 2020 – Join us!
North America | Europe | Middle East/Africa | Asia-Pacific

Network Change & Configuration Management

Accepted Solution

NetMRI CCS Archive command API call to get zip files off the box

Posts: 75
7614     0

I have been using the ARCHIVE command in CCS scripts very effectively.  I have a situation where I need NetMRI to gather some information not in the show running configuration and save it.


That part is easy.  Once it is saved, how can I find the files and get them off the box using the API?  The CCS Data Export only seems to applied to the last script run. I need to find a particular script and get those files.




If not in CCS, is there another way?

Re: NetMRI CCS Archive command API call to get zip files off the box

Posts: 412
7614     0

Two ways we can solve this, I have both scripts Smiley Happy


  1. You can run an external script to run the CCS script then store the output that you want locally.
  2. We can write a PERL script that takes the output and store it o the HTTP services of the NIOS for each device Smiley Happy
  3. I lied a 3rd Option - We can run a PERL script and store the output for each in the local SandBox


Which would you like?

I would go with the NIOS, cause you don't need an external server


Follow me on LinkedIn:

Re: NetMRI CCS Archive command API call to get zip files off the box

[ Edited ]
Posts: 32
7614     0


You can retrieve job logs, including the ones made by ARCHIVE: commands, using the API.


To simply save all of the job logs for a job (for all devices), you can use job->job_archive(). This requires that you know the Job ID (which you can find using another API call), and the date the job was executed. Something like this:


# First, select a job.
# This just chooses the first successfully completed for a given day.
# Anything that returns a single job would work.
print "Selecting a job...\n";
my @jobs = $netmri->broker->job->find({
      op_completed_at     => 'like',
      val_c_completed_at  => '2017-07-05%',
      op_status           => '=',
      val_c_status        => 'OK'
my $job = $jobs[0];

# Dump job archive to local file.

$localfilename = 'NetMRI_Job_' . $job->JobID . '';
print "Writing to $localfilename...\n";

open (OUTFILE, ">>$localfilename");
my $archive = $netmri->broker->Job->job_archive({
      id         => $job->JobID,
      started_at => '2017-07-05'
print (OUTFILE $archive);
close (OUTFILE);


Another approach is to save a separate archive for each device the job was run against, by cycling through the Job Details and using the job_detail->device_files() API call for each one.



Re: NetMRI CCS Archive command API call to get zip files off the box

Posts: 127
7615     0

Hi Sif - 


I'm trying to write a Python script that runs a CCS job, which ARCHIVES the command output, then I want to download the ARCHIVED file.  All went well up to the point of the api call to download the file.  It works as HTTPS in a browser, and it works just using the option to list the available files, but when I try to get the specific file it dumps.


Any ideas?  Thanks in advance.


#This works

# This works
client.api_request('job_details/device_files', params={'JobID': 45, 'DeviceID': 290,})
{u'filenames': [u'output.log', u'source.ccs', u'custom.log', u'table.log', u'session.log', u'e-ntac-05g11-core-crt01.txt', u'']}

# This don't work
client.api_request('job_details/device_files', params={'JobID': 45, 'DeviceID': 290, 'filename': 'e-ntac-05g11-core-crt01.txt'  })
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/netmrift/lib/python2.7/site-packages/infoblox_netmri-", line 227, in api_request
    return self._make_request(url=url, method="post", data=data)
  File "/home/netmrift/lib/python2.7/site-packages/infoblox_netmri-", line 103, in _make_request
    return self._send_request(url, method, data, extra_headers)
  File "/home/netmrift/lib/python2.7/site-packages/infoblox_netmri-", line 130, in _send_request
    return res.json()
  File "/home/netmrift/.local/lib/python2.7/site-packages/requests-2.18.4-py2.7.egg/requests/", line 884, in json
    self.content.decode(encoding), **kwargs
  File "/usr/lib64/python2.7/site-packages/simplejson/", line 516, in loads
    return _default_decoder.decode(s)
  File "/usr/lib64/python2.7/site-packages/simplejson/", line 374, in decode
    obj, end = self.raw_decode(s)
  File "/usr/lib64/python2.7/site-packages/simplejson/", line 404, in raw_decode
    return self.scan_once(s, idx=_w(s, idx).end())
simplejson.scanner.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Re: NetMRI CCS Archive command API call to get zip files off the box

Posts: 412
7615     0

Can you post the entire script?


Are you using the RestAPI or the Client

Follow me on LinkedIn:

Re: NetMRI CCS Archive command API call to get zip files off the box

[ Edited ]
Posts: 127
7615     0


It's pretty incoherent and untested at this stage, but as you wish.  Now I'll have to post the final product when done Smiley Wink


Please see my updated post with the solution, at least until Sif helps figure
out the job_details/device_files python api call.

Re: NetMRI CCS Archive command API call to get zip files off the box

Posts: 127
7615     0

Sif - 


I can get a curl command to work, but just not the Python api.


curl -k1 -u myuserid:mypassword --data "JobID=45&DeviceID=290&filename=source.ccs" https://mynetmri/api/3.3/job_details/device_files

Re: NetMRI CCS Archive command API call to get zip files off the box

[ Edited ]
Posts: 127
7615     0

I did find a work around using 'requests', but hate the idea of authenticating another time in the script.  At least it works now and returns the command result.


In order for this to work, one must change the 'Ad Hoc Command Batch' CCS script from:



	ARCHIVE ($Name.txt): $Commands_to_be_Executed

Then execute the external python script with 3 parameters. My first param indicates which NetMRI to run this on, the second is the device's name, and lastly is the command to execute:

python ntac mydevicename 'show run'

Below is the script.  Easy to modify to suit your own needs like making it a function in another script, but use cautiously, I don't think it would be good to create 1000 jobs at one time Smiley Wink  The NetMRI_AuthData is nothing more than a means of hiding some password information.  I have not included this below and assume you can subsitute your own auth parameters.


(The job TimeOut check and kill job has not been tested, and below is the sanitized version which I apologize in advanced if I created a syntax error someplace)


# -*- coding: utf-8 -*-
import sys, requests, json, time
import infoblox_netmri
from infoblox_netmri.client import InfobloxNetMRI

# Import function with auth data
from NetMRIProdAuth import NetMRI_AuthData

# Login to NetMRI: sys.argv[1] must be 'OC', 'prod' or 'ntac'
AuthData = NetMRI_AuthData(sys.argv[1])
client = infoblox_netmri.client.InfobloxNetMRI(

def run_adhoc(d_name, cmdline):

        devices = client.api_request('devices/find?DeviceName='+d_name, {'limit': 1})
        d_id = devices.values()[4][0]['DeviceID']

        JobID = client.api_request(
                'scripts/run', params={
                        'name': "Ad Hoc Command Batch",
                        'job_name': "Ad Hoc for "+AuthData['cli_username']+" - "+d_name,
                        'device_ids': (d_id,),
                        '$commands_to_be_executed': cmdline,
                        'username': AuthData['cli_username'],
                        'password': AuthData['cli_password'],
                        'enable_password': AuthData['cli_password']

        # Query the execution status, basically waiting for and EndTime
        JobComplete = False
        kounter = 0
        CmdOutput = ''
        while not JobComplete:

            # Get the job status, see if completed, loop for 600 seconds max.
            # J_Details.values()[4][0]['Status'] will contain 'OK', 'Error', 'Skipped', 'Pending'
            # J_Details.values()[4][0]['EndTime'] will not be null if job is completed
            J_Details = client.api_request('job_details/index', params={'JobID': JobID.values()[0],})

            JobStatus = J_Details.values()[4][0]['Status']
            if J_Details.values()[4][0]['EndTime'] > "":
                JobComplete = True
            elif kounter < 300: # Sleep for for a while but not too long
                kounter += 1
            elif kounter == 300:
                JobStatus = 'TimedOut'
                # Kill the Job, break out of the loop
                client.api_request('jobs/cancel', params={'JobID': JobID.values()[0],})
                return [JobStatus, CmdOutput]

        if JobStatus == 'OK':
            # Get the file
            p_data = {'JobID': JobID.values()[0], 'DeviceID': d_id, 'filename': d_name+'.txt' }
            response ='https://mynetmri/api/3.3/job_details/device_files', 
                            data=p_data, verify=False, auth=(AuthData['username'], AuthData['password']))
            CmdOutput = response.text

        return [JobStatus, CmdOutput]

result = run_adhoc(sys.argv[2], sys.argv[3])
print result[0]
print result[1]

print "Completed"

Re: NetMRI CCS Archive command API call to get zip files off the box

Posts: 1
7615     0
That's really cognitive information to know about such a indomitable and concrete stuffs. I stolidly respect that effort and hope to keep the good work as same as always.

Re: NetMRI CCS Archive command API call to get zip files off the box

Posts: 127
7615     0

The before mentioned issue with the job/details/device_files call now works in the 7.3.3 release of NetMRI.


>>> client.api_request('job_details/device_files', params={'JobID': 164, 'DeviceID': 290,})
{u'filenames': [u'output.log', u'source.ccs', u'custom.log', u'table.log', u'session.log', u'e-ntac-05g11-core-crt01.txt', u'']}
Showing results for 
Search instead for 
Do you mean 

Recommended for You