cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
2410
Views
5
Helpful
6
Replies

Why are my REST-API Cisco SD-WAN calls not working...

robbo79871
Level 1
Level 1

Hi, right now as i type this i'm currently on the Cisco DevNet sandbox using the SD-WAN sandbox, the main reason why i'm using it at the moment is to play around with REST-API calls to it. However no matter what call i try to do i always receive this back in the response:

>>> arp= requests.get('https://10.10.20.90:8443/dataservice/device/arp?deviceI
d=10.10.20.80', verify=False)
C:\Users\<REMOVED>\AppData\Local\Programs\Python\Python38-32\lib\site-packages\urllib
3\connectionpool.py:979: InsecureRequestWarning: Unverified HTTPS request is bei
ng made to host '10.10.20.90'. Adding certificate verification is strongly advis
ed. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnin
gs
  warnings.warn(
>>>
>>> print(arp.text)
<html>
  <head>
    <title>Cisco vManage</title>
    <link rel="stylesheet" type="text/css" href="/login.css">
    <link rel="stylesheet" type="text/css" href="/fonts/font-awesome-4.2.0/css/f
ont-awesome.min.css">
        <link rel="stylesheet" type="text/css" href="/bootstrap.min.css">
        <script type="text/javascript" src="/javascript/jquery.js"></script>
        <link rel="icon" type="image/ico" href="/images/favicon.ico"/>
    <script>
      var count = 1, max = 30;
      function init(){
        var rebootBlock = document.getElementById('reboot_message');
        rebootBlock.style.display = "none";
        var loginBlock = document.getElementById('login_message');
        loginBlock.style.display = "block";
        checkServerStatus();
      }
      function checkServerStatus() {
        if(count <= max){
          var xhr = new XMLHttpRequest();
          xhr.open("GET", "/dataservice/client/server/ready", true);
          xhr.onload = function (e) {
            if (xhr.readyState === 4) {
              if (xhr.status === 200) {
                var rebootBlock = document.getElementById('reboot_message');
                rebootBlock.style.display = "none";
                var loginBlock = document.getElementById('login_message');
                loginBlock.style.display = "block";
              } else {
                var rebootBlock = document.getElementById('reboot_message');
                rebootBlock.style.display = "block";
                var loginBlock = document.getElementById('login_message');
                loginBlock.style.display = "none";
                count++;
                setTimeout(checkServerStatus, 10000);
              }
            }
          };
          xhr.onerror = function (e) {
            count++;
            setTimeout(checkServerStatus, 10000);
          };
          xhr.send(null);
        }else{
          var rebootBlock = document.getElementById('reboot_message');
          rebootBlock.style.display = "none";
          var loginBlock = document.getElementById('login_message');
          loginBlock.style.display = "block";
        }
      }
      function validateForm() {
        if(loginForm.j_username.value.length==0 || loginForm.j_username.value=="
")
        {
          showErrorMessage("Invalid Username.");
          document.getElementById("j_username").className="login-input-error";
          return false;
        } else if(loginForm.j_password.value.length == 0 || loginForm.j_password
.value=="")
        {
          showErrorMessage("Invalid Password.")
          document.getElementById("j_password").className="login-input-error";
          return false;
        } else {
          hideErrorMessage();
          return true;
        }
      }

      function showErrorMessage(msg) {
        document.getElementById("errorMessageBox").innerHTML=msg;
      };

      function hideErrorMessage() {
        document.getElementById("errorMessageBox").innerHTML=' ';
        document.getElementById("j_username").className="login-input-value";
        document.getElementById("j_password").className="login-input-value";
      }
    </script>
  </head>
  <body onload="init()">
      <div name="Login" class="loginContainer">
      <div class="loginInnerContainer">
        <div class="productCategory">Cisco SD-WAN</div>
        <form class="loginFormStyle" name="loginForm" id="loginForm" method="POS
T" action="j_security_check" onsubmit="return validateForm()" autocomplete="off"
>
          <div name="logoMainContainer"  class="logoMainContainer"></div>
          <div class="brand-logo-text"><span>Cisco vManage</span></div>
          <p id="errorMessageBox" name="errorMessageBox" class='errorMessageBox
'></p>
          <div id="reboot_message" class="reboot-message-block">
            <div class="reboot-message">Server is initializing. Please wait.</di
v>
            <i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i>
          </div>
          <div id="login_message" style="display: none;">
            <div class='onyx-groupbox login-wrap' name="inputFields">
              <div class="onyx-input-decorator login-input">
                <input type="text" class="login-input-value"  size="18"
                     id="j_username" name="j_username" maxlength="64" placeholde
r="Username" value="" onfocus="hideErrorMessage()" autofocus />
              </div>
              <div class="onyx-input-decorator login-input">
                <input type="password" class="login-input-value"  size="18"
                     id="j_password" name="j_password" placeholder="Password"  v
alue="" onfocus="hideErrorMessage()" />
              </div>
            </div>
            <div class='onyx-sample-tools login-wrap'>
              <input type="submit"  name="submit"  value="Log In" class="login-b
utton"  />
            </div>
          </div>
        </form>
      </div>
      </div>
  </body>
</html>

It clearly isn't the JSON response coming back and i've no clue why and its driving me mad! 

I tried port 443, entering the creds in the request, even tried getting REST calls on the vManage box itself and STILL got the same error.  
Do i need to sign in a certain way, the GUI interface signs in fine with the username and password they supply, i've tried all sorts of ways of passing in authentication in the request but i can't get any of it to work. That's just a guess as well (authentication) for why it's failing, it could be anything.

>>> arp= requests.get('https://10.10.20.90:8443/dataservice/device/arp?deviceI
d=10.10.20.80', auth=('admin','C1sco12345'), verify=False)

RESPONSE:

{"error":{"message":"Device data error","details":" No device found for system I
P 10.10.20.80","code":"DEV0001"}}

 

6 Replies 6

Pshemek
Level 1
Level 1

Hi,

You need to authenticate via the /j_security_check call  (POST).

e.g. here's Java request definition:

 

postReq = new HttpPost("https://sandboxsdwan.cisco.com:8443/j_security_check");
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("j_username", <username>));
params.add(new BasicNameValuePair("j_password", <password>));
postReq.setEntity(new UrlEncodedFormEntity(params));

 

Hi, thanks for the reply. I'm still a bit confused with what i'm meant to do with the Java code there though and WHY is this not covered under any documentation from Cisco! Very poor if it isn't.
What should i do with the Java code you've provided? Thanks again for the help.

robbo79871
Level 1
Level 1

Anybody?

Hi,

1) You can try disabling ssl verification because the vmanage web server certificate may not be signed by a trusted CA

If using python, you can pass verify=false in your post.
Similarly curl, postman - have other ways to disable ssl verification.


2) You need to start with a login call

POST https://{{vmanage}}:{{port}}/j_security_check

3) Then if you are going to use POST/PUT calls later on, you also need to get XSRF-TOKEN
Refer https://www.cisco.com/c/en/us/td/docs/routers/sdwan/configuration/sdwan-xe-gs-book/cisco-sd-wan-API-cross-site-request-forgery-prevention.pdf

You can try some of these APIs at https://<vmanage-ip>:<port>/apidocs itself

Thanks,
Ajay

Hi, thanks for the reply, what do the double curly braces point to or indicate though? {{vmanage}}? Do they auto fill from somewhere. I'm using Python, why isn't any of this in the documentation. It seems a pretty important thing to leave off or make it very difficult to find.

Thanks, i look forward to your response.

Hi,

 

Please ignore the double curly braces . Just use the vmanage ip and port directly  https://vmanage-ip:vmanage-port/... .

There is a sample script below  which does login before getting information about devices using another API.

https://sdwan-docs.cisco.com/Product_Documentation/Command_Reference/Command_Reference/vManage_REST_APIs/vManage_REST_APIs_Overview/Using_the_vManage_REST_APIs#Establish_a_Session_to_the_vManage_Server

 

You can also follow some sample scripts at https://github.com/suchandanreddy e.g. https://github.com/suchandanreddy/sdwan-apis/blob/master/code_samples/vmanage_apis.py

Review Cisco Networking for a $25 gift card