cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
3615
Views
3
Helpful
28
Replies

SDWAN VManager Moving a device to an existing Template

wolfcaptain2002
Level 1
Level 1

Hello Everyone,

I need assistance with the Vmanager API, I need to reattach a device that in CLI mode to an existing template. I have used multiple API calls such as https://vmanage-ip-address/dataservice/template/device/config/attachfeature and /attachcli. These calls are being processed by the vmanager but is not moving the device to said template. Can anyone assist with the proper process or calls needed to reattach a device to an existing template?

 

Thank you!

28 Replies 28

Hello @Torbjørn,

Thank you for providing this answer, I do see the "/attachfeature" call is working a lot more smoothly. Once it runs through the checks it gives me the error.

Failed to update configuration - com.viptela.vmanage.server.deviceconfig.template.TemplateException: com.viptela.vmanage.server.deviceconfig.template.TemplateException: java.lang.NullPointerException']

Nullpointer mentions it cant find a variable if im not mistaken.

Thank you!

You are correct. The device template already has feature templates attached and we are just reattaching the device template. The SD-WAN manager requires that you use separate endpoints when handling feature template based device templates(/attachfeature) and cli based device templates(/attachcli).

If want to alter the feature template based device template(attach/remove feature templates you have to use the /template/device/feature endpoint instead.

Happy to help! Please mark as helpful/solution if applicable.
Get in touch: https://torbjorn.dev

Ouch, that's not ideal! I will reserve the sandbox and have another look.

Happy to help! Please mark as helpful/solution if applicable.
Get in touch: https://torbjorn.dev

Hello @Torbjørn  I appreciate your help. All I want is to reattach the feature template back onto a device. Here is function I was using. Thank you again!

def attach_template(template_id, device_id
URL = f'https://{vmanage}/dataservice/template/device/config/attachfeature'

headers = {
'Content-Type': 'application/json',
'X-XSRF-TOKEN': f'{Token}',
'Cookie': f'JSESSIONID={Cookie}'
}

# Simplified data structure matching API documentation
data = {
"deviceTemplateList": [
{
"templateId": "c9ef3b34-a096-4744-9e37-866276deb2a0",
"device": [
{
"csv-status": "complete",
"csv-deviceId": "C8K-C9DF615F-ABE7-1573-2BB1-288797F1B78B",
"csv-deviceIP": "10.10.1.17",
"csv-host-name": "Site3-cEdge01",
"//system/host-name": "Site3-cEdge01",
"//system/system-ip": "10.10.1.17",
"//system/site-id": "1003",
"csv-templateId": "c9ef3b34-a096-4744-9e37-866276deb2a0",
"selected": "true"
}
],
"isEdited": False,
"isMasterEdited": False
}
]
}

# Make the attachment request
response = requests.post(URL, headers=headers, verify=False, data=json.dumps(data))
response_data = response.json()
print("Attachment response:", response_data)

if 'id' in response_data:
# Monitor the task status
monitor_url = f'https://{vmanage}/dataservice/device/action/status/{response_data["id"]}'
for _ in range(30 # Check status for up to 5 minutes
monitor_response = requests.get(monitor_url, headers=headers, verify=False)
status = monitor_response.json()
print("Status:", status)

if status.get('status') == 'Success':
return True
elif status.get('status') in ['Failure', 'Failed']:
print("Failed:", status.get('message', 'No error message'))
return False

time.sleep(10)

return False

No problem! 

Just to ensure that we are on the same page: a feature template is a small template describing configuration of a given feature. A device template is what you apply to a network device and can either be a CLI based device template or a feature template based device template. The latter consists of a collection of feature templates that makes up a full device config and is what this API endpoint handles. 

Here is a new version of your function:

 

def attach_template(template_id, device_id, token, cookie ):
    url = f'https://10.10.20.90/dataservice/template/device/config/attachfeature'

    headers = {
        'Content-Type': 'application/json',
        'X-XSRF-TOKEN': token,
        'Cookie': f"JSESSIONID={cookie}"
    }

    data = {
        "deviceTemplateList": [{
            "templateId": template_id,
            "device": [
                {
                    "selected": "true",
                    "csv-deviceId": "C8K-C9DF615F-ABE7-1573-2BB1-288797F1B78B",
                    "csv-deviceIP": "10.10.1.18",
                    "csv-host-name": "Site3-cEdge02",
                    "/1/vpn-instance/ip/route/vpn_1_ip_route/prefix": "TEMPLATE_IGNORE",
                    "/1/vpn-instance/ip/route/vpn_1_ip_route/next-hop/vpn_1_next_hop_ip_address/address": "TEMPLATE_IGNORE",
                    "/1/vpn_1_if_name/interface/if-name": "GigabitEthernet3",
                    "/1/vpn_1_if_name/interface/description": "port.site3-sw01",
                    "/1/vpn_1_if_name/interface/ip/address": "10.10.25.1/24",
                    "/512/vpn-instance/ip/route/0.0.0.0/0/next-hop/vpn_512_next_hop_ip_address/address": "10.10.20.254",
                    "/512/vpn_512_if_name/interface/if-name": "GigabitEthernet1",
                    "/512/vpn_512_if_name/interface/description": "port.sbx-mgmt",
                    "/512/vpn_512_if_name/interface/ip/address": "10.10.10.1/24",
                    "/0/vpn-instance/ip/route/0.0.0.0/0/next-hop/vpn_0_mpls_next_hop_ip_add/address": "10.10.23.49",
                    "/0/vpn-instance/ip/route/0.0.0.0/0/next-hop/vpn_0_internet_next_hop_ip_add/address": "10.10.23.49",
                    "/0/vpn_0_internet_int_name/interface/if-name": "GigabitEthernet2",
                    "/0/vpn_0_internet_int_name/interface/description": "internet-link",
                    "/0/vpn_0_internet_int_name/interface/ip/address": "10.10.23.50/30",
                    "//system/host-name": "Site3-cEdge02",
                    "//system/system-ip": "10.10.1.18",
                    "//system/site-id": "1003"
                }
            ],
            "isEdited": False,
            "isMasterEdited": False
        }]
    }

    response = requests.post(url, headers=headers, verify=False, data=json.dumps(data))
    response_data = response.json()
    print("Attachment response:", response_data)

    if 'id' in response_data:
        # Monitor the task status
        monitor_url = f'https://10.10.20.90/dataservice/device/action/status/{response_data["id"]}'
        for _ in range(30):
            monitor_response = requests.get(monitor_url, headers=headers, verify=False)
            status = monitor_response.json()
            print("Status:", status)

            if status["summary"]["status"] == 'done':
                return True
            elif status["summary"]["status"] in ['Failure', 'Failed']:
                print("Failed:", status.get('message', 'No error message'))
                return False

            time.sleep(10)

    return False

 

A few changes I've made:

  • Device IP, ID and hostname all refer to cEdge02 as this previously was a mix of cEdge02 and cEdge01 values
  • All required parameters have now been set, I copied the ones in @bigevilbeards script. 
  • I corrected the value used for verification of status to ["summary"]["status"].

This is functionally the same as the previous script but simplified for demonstration purposes. I would look at the previous script to see a better example of how this could be implemented. 

Let me know if this works for you.

Happy to help! Please mark as helpful/solution if applicable.
Get in touch: https://torbjorn.dev

@Torbjørn nice catch on the feature template API endpoint. Now you mentioned this when i look back over the capture i did with developer tools, its says 'feature' when doing the action on the UI.

 

    "data": [
        {
            "activity": [
                "[28-Nov-2024 15:05:57 UTC] Configuring device with feature template: Site3-cEdge02",
                "[28-Nov-2024 15:05:58 UTC] Checking and creating device in vManage",
                "[28-Nov-2024 15:05:59 UTC] Generating configuration from template",
                "[28-Nov-2024 15:06:05 UTC] Device is online",
                "[28-Nov-2024 15:06:05 UTC] Updating device configuration in vManage",
                "[28-Nov-2024 15:06:05 UTC] Sending configuration to device"
            ],
            "local-system-ip": "10.10.1.18",
            "statusType": "push_feature_template_configuration",
            "scheduledAction": false,
            "system-ip": "10.10.1.18",
            "site-id": "1003",
            "templateId": "2c30ea87-42d8-40b4-b2ae-5ba8c33005ce",
            "uuid": "C8K-C9DF615F-ABE7-1573-2BB1-288797F1B78B",
            "tenant-id": "default",
            "@rid": 3829,
            "actionConfig": "{\"csv-status\":\"complete\",\"csv-deviceId\":\"C8K-C9DF615F-ABE7-1573-2BB1-288797F1B78B\",\"csv-deviceIP\":\"10.10.1.18\",\"csv-host-name\":\"Site3-cEdge02\",\"/512/vpn_512_if_name/interface/description\":\"port.sbx-mgmt\",\"/512/vpn-instance/ip/route/0.0.0.0/0/next-hop/vpn_512_next_hop_ip_address/address\":\"10.10.20.254\",\"/1/vpn_1_if_name/interface/ip/address\":\"10.10.25.1/24\",\"//system/site-id\":\"1003\",\"/512/vpn_512_if_name/interface/ip/address\":\"10.10.10.1/24\",\"/0/vpn-instance/ip/route/0.0.0.0/0/next-hop/vpn_0_mpls_next_hop_ip_add/address\":\"10.10.23.49\",\"/1/vpn-instance/ip/route/vpn_1_ip_route/next-hop/vpn_1_next_hop_ip_address/address\":\"TEMPLATE_IGNORE\",\"//system/host-name\":\"Site3-cEdge02\",\"/0/vpn_0_internet_int_name/interface/ip/address\":\"10.10.23.50/30\",\"/1/vpn-instance/ip/route/vpn_1_ip_route/prefix\":\"TEMPLATE_IGNORE\",\"//system/system-ip\":\"10.10.1.18\",\"/0/vpn-instance/ip/route/0.0.0.0/0/next-hop/vpn_0_internet_next_hop_ip_add/address\":\"10.10.23.49\",\"/1/vpn_1_if_name/interface/if-name\":\"GigabitEthernet3\",\"/512/vpn_512_if_name/interface/if-name\":\"GigabitEthernet1\",\"/0/vpn_0_internet_int_name/interface/if-name\":\"GigabitEthernet2\",\"/0/vpn_0_internet_int_name/interface/description\":\"internet-link\",\"/1/vpn_1_if_name/interface/description\":\"port.site3-sw01\",\"csv-templateId\":\"2c30ea87-42d8-40b4-b2ae-5ba8c33005ce\"}",
            "processId": "push_feature_template_configuration-c160cc6a-ec0f-4bcc-af22-f9b56f82a027",
            "device-type": "vedge",
            "action": "push_feature_template_configuration",
            "startTime": 1732806357608,
            "order": 0,
            "vmanageIP": "10.10.1.1",
            "host-name": "Site3-cEdge02",
            "deviceID": "C8K-C9DF615F-ABE7-1573-2BB1-288797F1B78B",
            "statusId": "in_progress",
            "currentActivity": "Sending configuration to device",
            "deviceModel": "vedge-C8000V",
            "validity": "valid",
            "requestStatus": "received",
            "lastUpdateTime": 1732806365999,
            "status": "In progress"
        }
    ],

 

A odd issue, as you would expect the logs to flag this other than the 'null'

28-Nov-2024 17:50:03,458 UTC INFO  [e76b6692-6ce6-40b8-aa29-3c885cc93d9d] [Manager] [MasterTemplateDeviceRestfulResource] (default task-210) |default| User: admin , trying to attachCli
28-Nov-2024 17:50:03,608 UTC INFO  [] [] [DeviceTemplateMessageBuilder] (push_file_template_configuration Thread) || Updating lease time for useradmin
28-Nov-2024 17:50:03,670 UTC INFO  [] [] [ConfigureDeviceWithFileTemplateActionProcessor] (elastic-63) || Acknowledged messages in time 18
28-Nov-2024 17:50:03,856 UTC INFO  [] [] [MasterTemplateDAO] (Process device action - Push CLI Template Configuration) || updateCopyEditedTemplateStatus templateVertex com.viptela.vmanage.server.datastore.neo4j.Neo4JVertex
@2f986ba8 isMTT false
28-Nov-2024 17:50:03,859 UTC INFO  [] [] [ConfigureDeviceWithFileTemplateActionProcessor] (Process device action - Push CLI Template Configuration) || CLI template thread pool size  8 Server CPU core 4 VDaemon count 4
28-Nov-2024 17:50:03,872 UTC INFO  [] [] [ConfigureDeviceWithFileTemplateActionProcessor] (device-action-push_file_template_configuration-40) || ConfigConfigPerf: processCLITemplate. Start Id. templateId 2c30ea87-42d8-40b4
-b2ae-5ba8c33005ce
28-Nov-2024 17:50:03,938 UTC ERROR [] [] [ConfigureDeviceWithFileTemplateActionProcessor] (device-action-push_file_template_configuration-40) || Failed to CLI configure.
java.lang.NullPointerException: null
	at java.lang.String.<init>(String.java:236) ~[?:?]
	at com.viptela.vmanage.server.deviceaction.processor.config.ConfigureDeviceWithFileTemplateActionProcessor.processCLITemplate(ConfigureDeviceWithFileTemplateActionProcessor.java:364) [vmanage-server-1.0.0-SNAPSHOT.
jar:?]
	at com.viptela.vmanage.server.deviceaction.processor.config.ConfigureDeviceWithFileTemplateActionProcessor$CLITemplateWorker.process(ConfigureDeviceWithFileTemplateActionProcessor.java:479) [vmanage-server-1.0.0-SN
APSHOT.jar:?]
	at com.viptela.vmanage.server.deviceaction.processor.config.DeviceTemplatePushStatusWorker.startDeviceAction(DeviceTemplatePushStatusWorker.java:54) [vmanage-server-1.0.0-SNAPSHOT.jar:?]
	at com.viptela.vmanage.server.deviceaction.scheduler.AbstractSchedulerWorker.call(AbstractSchedulerWorker.java:100) [vmanage-server-1.0.0-SNAPSHOT.jar:?]
	at com.viptela.vmanage.server.deviceaction.scheduler.AbstractSchedulerWorker.call(AbstractSchedulerWorker.java:57) [vmanage-server-1.0.0-SNAPSHOT.jar:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
	at java.lang.Thread.run(Thread.java:834) [?:?]
28-Nov-2024 17:50:04,029 UTC INFO  [] [] [TemplateLock] (device-action-push_file_template_configuration-40) || TemplateLock: removeLock processId: push_file_template_configuration-9d280fd9-a6e1-40df-bfc4-2fdb283e8ca6
28-Nov-2024 17:50:04,032 UTC INFO  [] [] [TemplateLock] (device-action-push_file_template_configuration-40) || Removing template lock - Lock with processId push_file_template_configuration-9d280fd9-a6e1-40df-bfc4-2fdb283e8
ca6 not found
28-Nov-2024 17:50:04,064 UTC INFO  [] [] [ConfigureDeviceWithFileTemplateActionProcessor] (device-action-push_file_template_configuration-40) || ConfigPerf: processCLITemplate. End. templateId 2c30ea87-42d8-40b4-b2ae-5ba8c
33005ce
28-Nov-2024 17:50:04,064 UTC ERROR [] [] [ConfigureDeviceWithFileTemplateActionProcessor] (Process device action - Push CLI Template Configuration) || [CLI_TEMPLATE] Master template push failed  Task Id [push_file_template
_configuration-9d280fd9-a6e1-40df-bfc4-2fdb283e8ca6]  Device Id [C8K-C9DF615F-ABE7-1573-2BB1-288797F1B78B]  Template Id [2c30ea87-42d8-40b4-b2ae-5ba8c33005ce]  Schedule Time [28-Nov-2024 17:50:03 UTC]  Process Start Time [
28-Nov-2024 17:50:03 UTC]  Process End Time [28-Nov-2024 17:50:04 UTC]  Total time taken [204 ms].  with exception java.lang.NullPointerException
	at deployment.vmanage.war//com.viptela.vmanage.server.deviceaction.processor.config.ConfigureDeviceWithFileTemplateActionProcessor.processActionOnMasterTemplate(ConfigureDeviceWithFileTemplateActionProcessor.java:2
47)
	at deployment.vmanage.war//com.viptela.vmanage.server.deviceaction.processor.config.ConfigureDeviceWithFileTemplateActionProcessor.processDeviceAction(ConfigureDeviceWithFileTemplateActionProcessor.java:430)
	at deployment.vmanage.war//com.viptela.vmanage.server.deviceaction.processor.AbstractDeviceActionProcessor.runDeviceAction(AbstractDeviceActionProcessor.java:400)
	at deployment.vmanage.war//com.viptela.vmanage.server.deviceaction.processor.AbstractDeviceActionProcessor$1.run(AbstractDeviceActionProcessor.java:144)
	at deployment.vmanage.war//com.viptela.vmanage.server.util.ThreadUtil$BookmarkedRunnable.run(ThreadUtil.java:49)
	at java.base/java.lang.Thread.run(Thread.java:834)
.
28-Nov-2024 17:50:04,118 UTC INFO  [] [] [TemplateLock] (Process device action - Push CLI Template Configuration) || TemplateLock: removeLock processId: push_file_template_configuration-9d280fd9-a6e1-40df-bfc4-2fdb283e8ca6
28-Nov-2024 17:50:04,121 UTC INFO  [] [] [TemplateLock] (Process device action - Push CLI Template Configuration) || Removing template lock - Lock with processId push_file_template_configuration-9d280fd9-a6e1-40df-bfc4-2fd
b283e8ca6 not found
28-Nov-2024 17:50:04,212 UTC INFO  [] [] [TemplateLock] (Process device action - Push CLI Template Configuration) || TemplateLock: removeLock processId: push_file_template_configuration-9d280fd9-a6e1-40df-bfc4-2fdb283e8ca6
28-Nov-2024 17:50:04,216 UTC INFO  [] [] [TemplateLock] (Process device action - Push CLI Template Configuration) || Removing template lock - Lock with processId push_file_template_configuration-9d280fd9-a6e1-40df-bfc4-2fd
b283e8ca6 not found
28-Nov-2024 17:50:04,240 UTC INFO  [] [] [TemplateRollbackManager] (Process device action - Push CLI Template Configuration) || Template Rollback Manager template type null, id 2c30ea87-42d8-40b4-b2ae-5ba8c33005ce with det
ails null lockState null and accept false
28-Nov-2024 17:50:04,240 UTC ERROR [] [] [TemplateRollbackManager] (Process device action - Push CLI Template Configuration) || ConfigTemplateType is null. Returning without finalizing..
Manager:~$           timed out waiting for input: auto-logout

 

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

wolfcaptain2002
Level 1
Level 1

Hello @Torbjørn and @bigevilbeard 

Are you aware of an way or API call to get all the feature templates associated with a existing template for example how are you able to find the feature mentioned below preferably without GUI . I am new to SDWAN and appreciate all your help.

Thank you!

"/0/vpn_0_internet_int_name/interface/ip/address": "10.10.23.50/30",

 

If i understand your request, both GET requests might be what you are looking for - 

/dataservice/template/feature - Lists available feature templates
/dataservice/template/feature/attached/{deviceModel} - Lists feature templates attached to a specific device model
Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io

In addition to the endpoints @bigevilbeard listed above I think you might find this API endpoint useful: /template/device/{templateId}/featuretemplates

EDIT: The line you listed at the bottom is a variable and it's associated value. Are you trying to get the variables required for attaching the device template?

Happy to help! Please mark as helpful/solution if applicable.
Get in touch: https://torbjorn.dev

wolfcaptain2002
Level 1
Level 1

Hello @Torbjørn ,

Yes that is the goal to get the feature value and variable.

You can construct the required variable-paths/names by if you fetch the list of feature templates for the device template with /template/device/object/{templateId}, then fetch the feature templates with /template/feature/definition/{templateId} and look at the variable definitions. AFAIK there is no easier way to do this through the API.

I would probably set the variable names statically in your project unless you have a usecase that requires that you handle this in a more flexible manner. The first step you would need to take to be able to construct the variable paths/names dynamically is to figure out the exact naming convention for variables as this doesn't seem to be documented anywhere.

Happy to help! Please mark as helpful/solution if applicable.
Get in touch: https://torbjorn.dev

wolfcaptain2002
Level 1
Level 1

Hello @Torbjørn and @bigevilbeard ,

As you mentioned, the easiest way to reattach is by making two calls and matching the variable to the description. I see that feature templates have already been applied. Based on the image I provided under the devices attached column is it possible to reattach without specifying feature templates as I only need to reattach? All this been has slightly confusing since my lack of understanding of SD-WAN, I appreciate your help!

 

You must specify the required variables when reattaching the device template, but you don't have to add the individual feature templates to the device template if the device template is already complete. You can attach the device template in a single call as demonstrated previously with the /template/device/config/attachfeature endpoint if you know which variables need to be set and what values they should have.

Let me know if this clarifies it.

Happy to help! Please mark as helpful/solution if applicable.
Get in touch: https://torbjorn.dev

@wolfcaptain2002 could be wrong here, sure you can do this with PUT /template/device/{templateId} - https://developer.cisco.com/docs/sdwan/sd-wan-vmanage-v20-14/ 

Please mark this as helpful or solution accepted to help others
Connect with me https://bigevilbeard.github.io