cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1217
Views
1
Helpful
2
Replies

SDWAN - vManage API - update device configuration using device templat

lak141516
Level 1
Level 1

Hi,

I would appreciate if someone could help me with the below:

1. The goal is to update the device configuration using the device template - using Python

2. So the step - by- step would be as below as I think: 

   - Step1: authentication to vManage, get cookie and token. This is done successfully and able to use these for GET 

   - Step2: get the templateID and deviceID (UUID) then POST to /dataservice/template/device/config/input:

          + post function: 

 

 

 

    def postRequest(self, mountURL, payload):
        headers = {
            'Content-Type': "application/json",
            #'cache-control': "no-cache",
            'X-XSRF-TOKEN': self.token,
            'Cookie': self.cookie
        }
        url = self.base_url + mountURL
        response = requests.request(
            "POST", url, headers=headers, data=payload, verify=False)
        return response

 

 

          + With templateid and UUID collected successfully (as string) - construct the payload:

 

 

payload = {"templateId": template_id, "deviceIds": deviceIds, "isEdited": False, "isMasterEdited": False}

 

 

          + Generate device input variables by POST to /dataservice/template/device/config/input

 

 

mountURL = f'/dataservice/template/device/config/input'
payload = json.dumps(payload)
response = base.postRequest(self, mountURL, payload)

 

 

          + However instead of getting 200, the response is 500 with error as below

 

 

{"error":{"message":"Server error","details":"vManage server experience an unexpected error,If the problem persists, please contact your administrator for details.","code":"REST0001"}}

 

 

          + I tried to run test using the /apidocs/#/Configuration%20-%20Device%20Template/createDeviceInput directly from the vManage - get the same error 

image.png

          + Log from the vmanage-server.log - showed an exception

 

 

07-Feb-2024 10:55:05,397 UTC INFO  [vManage01] [SystemDeviceDAO] (default task-1128) |default| RESOURCE_GROUP=resourceGroup name=global
07-Feb-2024 10:55:07,324 UTC ERROR [GB-LND-LONPWG-vManage01] [RestfulDefaultExceptionMapper] (default task-1128) |default| Uncaught exception thrown by REST 
java.lang.ClassCastException: class org.glassfish.json.JsonStringImpl cannot be cast to class javax.json.JsonArray (org.glassfish.json.JsonStringImpl is in unnamed module of loader 'org.glassfish.jakarta.json@1.1.6' @293a5bf6; javax.json.JsonArray is in unnamed module of loader 'javax.json.api@1.1.5' @5b8dfcc1)
        at org.glassfish.json.JsonObjectBuilderImpl$JsonObjectImpl.getJsonArray(JsonObjectBuilderImpl.java:213) ~[jakarta.json-1.1.6.jar!/:1.1.6]
        at com.viptela.vmanage.server.deviceconfig.template.master.MasterTemplateDeviceRestfulResource.createDeviceInput(MasterTemplateDeviceRestfulResource.java:1196) ~[vmanage-server-1.0.0-SNAPSHOT.jar:?]
        at com.viptela.vmanage.server.deviceconfig.template.master.MasterTemplateDeviceRestfulResource$Proxy$_$$_WeldClientProxy.createDeviceInput(Unknown Source) ~[vmanage-server-1.0.0-SNAPSHOT.jar:?]
        at jdk.internal.reflect.GeneratedMethodAccessor260.invoke(Unknown Source) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
        at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:138) ~[resteasy-jaxrs-3.11.2.Final.jar!/:3.11.2.Final]
        at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:535) ~[resteasy-jaxrs-3.11.2.Final.jar!/:3.11.2.Final]
        at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:424) ~[resteasy-jaxrs-3.11.2.Final.jar!/:3.11.2.Final]
        at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$0(ResourceMethodInvoker.java:385) ~[resteasy-jaxrs-3.11.2.Final.jar!/:3.11.2.Final]
        at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:356) ~[resteasy-jaxrs-3.11.2.Final.jar!/:3.11.2.Final]
        at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:387) ~[resteasy-jaxrs-3.11.2.Final.jar!/:3.11.2.Final]
        at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:356) ~[resteasy-jaxrs-3.11.2.Final.jar!/:3.11.2.Final]
        at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:329) ~[resteasy-jaxrs-3.11.2.Final.jar!/:3.11.2.Final]
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:440) ~[resteasy-jaxrs-3.11.2.Final.jar!/:3.11.2.Final]
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:229) ~[resteasy-jaxrs-3.11.2.Final.jar!/:3.11.2.Final]
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:135) ~[resteasy-jaxrs-3.11.2.Final.jar!/:3.11.2.Final]
        at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:356) ~[resteasy-jaxrs-3.11.2.Final.jar!/:3.11.2.Final]
        at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:138) ~[resteasy-jaxrs-3.11.2.Final.jar!/:3.11.2.Final]
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:215) ~[resteasy-jaxrs-3.11.2.Final.jar!/:3.11.2.Final]

 

 

 

Would anyone work on this before and can give me some help please? It's strange that even using try now on apidocs also has similar issue.

Thanks in advanced,

Khoa

 

1 Accepted Solution

Accepted Solutions

Dan Frey
Cisco Employee
Cisco Employee

The uuid passed to deviceIds in the input api needs to be a list.

# Input
        payload = {"templateId":templateId,"deviceIds":[uuid],"isEdited":False,"isMasterEdited":False}
        api_url = "/template/device/config/input/"
        url = base_url + api_url
        response = requests.post(url=url, headers=headers, data=json.dumps(payload), verify=False)
        print(response.status_code)
        print(response.url)
#        print(response.text)

# Attach Template
        payload = {"deviceTemplateList":[{"templateId":templateId,"device":[{"csv-status":"complete","csv-deviceId":uuid,"csv-deviceIP":systemIp,"csv-host-name":hostName,"csv-templateId":templateId}],"isEdited":False}]}
        payload["deviceTemplateList"][0]["device"][0].update(dataYaml)
        print(json.dumps(payload, indent=4))
        api_url = "/template/device/config/attachcli/"
        url = base_url + api_url
        response = requests.post(url=url, headers=headers, data=json.dumps(payload), verify=False)
        print(response.status_code)
        print(response.url)
        print(response.text)

 

View solution in original post

2 Replies 2

Dan Frey
Cisco Employee
Cisco Employee

The uuid passed to deviceIds in the input api needs to be a list.

# Input
        payload = {"templateId":templateId,"deviceIds":[uuid],"isEdited":False,"isMasterEdited":False}
        api_url = "/template/device/config/input/"
        url = base_url + api_url
        response = requests.post(url=url, headers=headers, data=json.dumps(payload), verify=False)
        print(response.status_code)
        print(response.url)
#        print(response.text)

# Attach Template
        payload = {"deviceTemplateList":[{"templateId":templateId,"device":[{"csv-status":"complete","csv-deviceId":uuid,"csv-deviceIP":systemIp,"csv-host-name":hostName,"csv-templateId":templateId}],"isEdited":False}]}
        payload["deviceTemplateList"][0]["device"][0].update(dataYaml)
        print(json.dumps(payload, indent=4))
        api_url = "/template/device/config/attachcli/"
        url = base_url + api_url
        response = requests.post(url=url, headers=headers, data=json.dumps(payload), verify=False)
        print(response.status_code)
        print(response.url)
        print(response.text)

 

lak141516
Level 1
Level 1

thanks Dan for the advice, you saved my day. Next step for me is to modify the data and push back.

Thanks again.