cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
5389
Views
16
Helpful
11
Replies

API - GET ConfigVersions and CURL question

dasampson
Level 1
Level 1

Hey everyone,

I am having an issue trying to use CURL to GET ConfigVersion to work so that I can use the Config Diff.

Below, you will see that I can run the ConfigArchives success but get a 404 error when I try to use ConfigVersions.  Does anyone know what I am doing wrong?  Running PI 3.1.4 Update 01 and PI 3.1.5 Maintenance Release with Device Pack 8

Any help would be much appreciated.

[dsampson@mnet-ws-dave curl]$ curl -k "https://user:password@cpi/webacs/api/v1/data/ConfigArchives/582721"

<?xml version="1.0" ?>

<queryResponse type="ConfigArchives" responseType="getEntity" requestUrl="https://cpi/webacs/api/v1/data/ConfigArchives/582721" rootUrl="https://cpi/webacs/api/v1/data">

  <entity dtoType="configArchivesDTO" type="ConfigArchives" url="https://cpi/webacs/api/v1/data/ConfigArchives/582721">

    <configArchivesDTO displayName="582721" id="582721">

      <deviceIpAddress>10.10.10.10</deviceIpAddress>

      <deviceName>devicename.com</deviceName>

      <lastSuccessful>true</lastSuccessful>

    </configArchivesDTO>

  </entity>

</queryResponse>

[dsampson@mnet-ws-dave curl]$

[dsampson@mnet-ws-dave curl]$

[dsampson@mnet-ws-dave curl]$

[dsampson@mnet-ws-dave curl]$

[dsampson@mnet-ws-dave curl]$ curl -k "https://user:password@cpi/webacs/api/v1/data/ConfigVersions/582721"

<?xml version="1.0" ?>

<errorDocument>

  <httpResponseCode>404</httpResponseCode>

  <httpMethod>GET</httpMethod>

  <message>No such entity as ConfigVersions / 582,721.-PRS-101</message>

  <id>presentation.PRS-101</id>

  <uriPath>data/ConfigVersions/582721</uriPath>

  <queryParams>{}</queryParams>

</errorDocument>

[dsampson@mnet-ws-dave curl]$

[dsampson@mnet-ws-dave curl]$

[dsampson@mnet-ws-dave curl]$

[dsampson@mnet-ws-dave curl]$

1 Accepted Solution

Accepted Solutions

Spencer Zier
Cisco Employee
Cisco Employee

GET data/ConfigArchives and GET data/ConfigVersions are not sequenced with the same IDs.  The GET data/ConfigArchives resource let's you know, for the devices where a config archive was attempted, if the latest attempt was successful and if not, why not.  The GET data/ConfigVersions resource describes which config archives we have (which version, which files are part of it, when was it captured, from which device, and so on).  Among its output will be one or more fileId values, which can be passed to GET op/configArchiveService/extractSanitizedFile (to have sensitive information redacted/masked) or GET op/configArchiveService/extractUnsanitizedFile (to have sensitive information left intact).

So, after identifying a device in question with GET data/ConfigArchives and confirming the last attempt is successful, you should filter on GET data/ConfigVersions (for example, data/ConfigVersions?.full=true&deviceName=devicename.com) to get the details of the archive(s) and the fileIds.  I hope that helps

View solution in original post

11 Replies 11

Spencer Zier
Cisco Employee
Cisco Employee

GET data/ConfigArchives and GET data/ConfigVersions are not sequenced with the same IDs.  The GET data/ConfigArchives resource let's you know, for the devices where a config archive was attempted, if the latest attempt was successful and if not, why not.  The GET data/ConfigVersions resource describes which config archives we have (which version, which files are part of it, when was it captured, from which device, and so on).  Among its output will be one or more fileId values, which can be passed to GET op/configArchiveService/extractSanitizedFile (to have sensitive information redacted/masked) or GET op/configArchiveService/extractUnsanitizedFile (to have sensitive information left intact).

So, after identifying a device in question with GET data/ConfigArchives and confirming the last attempt is successful, you should filter on GET data/ConfigVersions (for example, data/ConfigVersions?.full=true&deviceName=devicename.com) to get the details of the archive(s) and the fileIds.  I hope that helps

That did work, thanks Spencer.  Now if I can ask another question that is related. (yell at me if I should branch this conversation).  I try to use the fileId that I received from in my ConfigVersions result in a extractSanitziedFile request but get an "Access is denied to Prime Infrastructure".  The user account that I am using has NBI Read and NBI Credential rights.  Do I need to add additional rights to be able to extract the file?

For extractSantizedFile, NBI Read should be the only group required.  Are you by chance using any external AAA providers (TACACS, RADIUS, etc.)?  If so, make sure they're configured correctly.  Upgrades and patches will sometimes change the task lists.

I checked on a 3.1.0 instance and it seems to be behaving correctly.  You're on 3.1.5 right?  Let me roll up to that version and check.

My api user account is a local user account on Prime Infrastructure. (we do use ISE for AAA auth normally for Prime).  Here is my curl statement and results.

[dsampson@mnet-ws-dave curl]$ curl -k "https://username:password@cpi/webacs/api/v1/op/configArchiveService/extractSanitziedFile?fileId=95032208"

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<link rel="stylesheet" href="https://community.cisco.com/webacs/styles/wcs.css" type="text/css">

<script type="text/javascript">

function windowTitle()

{

         var productName = 'Prime Infrastructure';

         if(productName=="Prime Infrastructure"){

         parent.document.title ="Access is denied to "+"Prime Infrastructure";

         }else if(productName=="Evolved Programmable Network Manager"){

         parent.document.title ="Access is denied to"+"EPN Manager";

         }

}

</script>

</head>

<body  onload="windowTitle();" class="popup" text="#000000" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">

<table width="100%" height="62" border="0" cellspacing="0" cellpadding="0">

  <tr>

    <td height="62" width="180"> </td>

    <td valign="bottom" style="background-color:#ffffff;>

      <div class="mainMenu">

        <table width="100%" border="0" cellspacing="0" cellpadding="0">

          <tr>

            <td height="43" valign="bottom">

            </td>

          </tr>

          <tr>

            <td bgcolor="FFFFFF" height="19">  </td>

          </tr>

        </table>

      </div>

    </td>

  </tr>

  <tr>

    <td valign="top">

      <div class="navBar">   </div>

    </td>

    <td valign="top">

      <div class="content">

       <table>

       <tr>

       <td class="pageTitleProp">

                                                                Access is denied to

                                                                Prime Infrastructure.

       <br>Please contact the network administrator</br>

       </td>

       </tr>

       </table>

      </div>

    </td>

  </tr>

</table>

<div class="alarms">  </div>

</body>

</html>

[dsampson@mnet-ws-dave curl]$

Ignore my last, it is because I spelled "sanitized" wrong.

Ah yeah, that would do it.  Glad that's solved

If you have any further questions please feel free to reach out.

I may have a related question (hope it's OK to piggy back off this post). I would like to have a simple config diff yes/no like what is in the GUI when I look under each device. I would like for me to be able to run the API and it spit out every device's name and if the startup config matches the running config with a yes/no to hand to compliance if/when we get audited. I REALLY don't want to have to go into every single device to see if it matches (very time consuming).

I've tried running api.request=("ConfigArchives") by itself with no additional parameters and I don't see a startup/run match there. I see a lastSuccessful which is still good to know, but not what I need. If i try to run api.request="configDiff") python blows up on me saying:

>>> api.request("configDiff")

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

  File "C:\Python27\lib\site-packages\piapi.py", line 397, in request

    return self.request_service(resource, params, timeout)

  File "C:\Python27\lib\site-packages\piapi.py", line 358, in request_service

    return self._parse(response)

  File "C:\Python27\lib\site-packages\piapi.py", line 180, in _parse

    raise PIAPIRequestError("An error has occured during the API invocation")

piapi.PIAPIRequestError: An error has occured during the API invocation

I'm new to APIs and am wanting to learn (new DC is possibly moving to ACI), so this is my first run at it.

Not sure what's happening with your Python script.  If you have the complete URL that you requested and the raw response you got from PI I could maybe provide some pointers as to what's wrong.

As to your use case, telling at a glance if running and startup configs are in sync, I'd suggest using our GET data/ConfigVersions resource.  Whereas GET data/ConfigArchives shows you all of the devices that we potentially have config archives for, and whether or not the last attempt to pull a config archive was successful, the ConfigVersions resource shows you each instance of a config archive.  For example, if you've archived the config a given device 12 times, then there will be 12 records in ConfigVersions for that device.  The diffType response parameter will let you know if the startup and running config are in sync with each other or not.  The isLast response parameter will be true for the latest config archive pulled for a given device.

So to find all of the devices with out-of-sync running and startup configs, based on the last config archive pulled, you'd query

/webacs/api/v2/data/ConfigVersions?.full=true&isLast=true&diffType=OUT_OF_SYNC

Oh, I should add, I think it's a good idea to continue to query the ConfigArchives resource, as it will let you know if PI is having problems archiving device configs.  But if you need to tell if the config is out of sync, again, use the above.

Hmm, when I try putting /webacs/api/v2/data/ConfigVersions?.full=true&isLast=true&diffType=OUT_OF_SYNC in the browser to get the XML output, it keeps prompting me to login, even when passing the user/pass through the URL. Other queries I've tried work fine.

But, it looks like running api.request("ConfigVersions", params={"diffType": "OUT_OF_SYNC"}) is scrolling tons of stuff on me. unfortunately, I see lots of "OUT_OF_SYNC"

I think that means a long day for me .

edit: I have another guy that works a little with programming that is going to make the output more readable for me.

Thanks for the help on this!

So, regarding CSV, the API doesn't return them (excepting one of the reporting services, which returns a zip of CSV files directly obtained from the reporting framework).  The reason being, CSV is a very linear, rigid format.  In many cases, we nest documents within other documents (like fileInfos which nest inside the configVersionsDTO); sometimes there's just one nested document, sometimes there's dozens (like interfaces from the InventoryDetails resource when reporting on a stacked switch).  For this reason, conversion to CSV is left as a client-side concern.

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: