This is a sample project to demonstrate an offline license reservation using the "Smart License Using Policy" process, which might be used if Smart License enabled devices are in an air-gapped network.
This project contains a Postman collection & set of Python scripts to help automate the license management process.
Using either method, you can:
[Step 1] Clone repo:
git clone <repo_url>
[Step 2] Import Postman Collection:
File > Import
Smart Licensing Using Policy Offline.postman_collection.json
& Smart Licensing.postman_environment.json
[Step 3] Configure required variables:
There are a number of environment variables for this collection. For all requests, only the following are required:
client_id
, client_secret
, smart_account
, virtual_account
, device_pid
, device_serial
, and license_tag
Step 3
secion for Python Install/Config for details on these variables[Step 1] Clone repo:
git clone <repo_url>
[Step 2] Install required dependencies:
pip install -r requirements.txt
[Step 3] Configure required variables:
.env-example
file & rename to .env
############## # SET THESE: CLIENT_ID="" CLIENT_SECRET="" SMART_ACCOUNT="" VIRTUAL_ACCOUNT="" DEVICE_SERIAL="" DEVICE_PID="" DEVICE_HOSTNAME="" LICENSE_TAG="" ##############
CLIENT_ID
& CLIENT_SECRET
- These are the Smart Licensing API credentials. Please follow the guide here on how to register a new application & obtain these credentials.SMART_ACCOUNT
- The target Smart Account domain to use for licensing requests. (Example: networkteam.company.local)VIRTUAL_ACCOUNT
- The target Virtual Account to use for licensing requests. (Example: US1-LAB-NETWORK)DEVICE_SERIAL
& DEVICE_PID
- These can be obtained on the target network device via the show license udi
command. (Example: UDI: PID:C8000V,SN:ABCDEF1234)DEVICE_HOSTNAME
- The device hostname to be attached to the license reservation requestLICENSE_TAG
- The ISO 19770-2 license tag (Example: regid.2019-03.com.cisco.DNA_HSEC,1.0_509c41ab-05a8-431f-95fe-ec28086e8844). This can be obtained in one of two ways:
show license tech support | include Entitlement
03 - Get License Usage by Tag
under the License Verification
section
01 - Get Auth Token
followed by 02 - Get SA/VA IDs
The Postman collection is structured in the order of operations for use. The collection contains a number of tests for each request, which will query the response body & save the required variables for future requests.
All processes (reserve license, delete license, upload report, etc) must start with the Authentication & SA/VA ID
section (Steps 1 & 2 here).
[Step 1] Get Authentication Token
Authentication & SA/VA ID
> 01 - Get Auth Token
client_id
& client_secret
to Cisco SSO, and provide an access token for Smart Licensing requestsaccess_token
variable[Step 2] Collect Smart Account & Virtual Account ID Numbers
For all requests, we'll need the unique identifiers for the Smart Account & Virtual Account.
Authentication & SA/VA ID
> 02 - Get SA/VA IDs
account_id
& virtual_account_id
fields from the response for future requests[Step 3] Request License Reservation
License Reservation
> 03 - Get SA/VA IDs
poll_id
field[Step 4] Check License Reservation Status
Run the Postman request: License Reservation
> 04 & 06 - Check License Request / Obtain License / Get License ACK
status
of OK_POLL
status
of COMPLETE
If a license was successfully generated & reserved, the license data will be in the smart_license
field
License can be placed on a TFTP server & installed on the device with the following command:
license smart import <bootflash|tftp>:lic.txt
[Step 5] Submit License Usage Report
Note: This step can be troublesome in Postman, as it will require you to pull certain info from the device usage report & apply it in Postman exactly as it is in the device report. Any mis-matches will be rejected by the Smart Licensing server. The included python scripts will automatically parse & structure the POST payload in the format Smart Licensing is expecting.
Collect device usage reports from the device with the following command:
license smart save usage all file <bootflash|tftp>:<filename>
Open the device usage report in a text editor, and find the latest usage report for the license you are reserving.
Within that usage report, copy the report payload & enter it in the Postman environment variable usage_payload
"{\"asset_identification\":{\"asset\":
and ending with \"value\":{\"type\":\"COUNT\",\"value\":\"1\"}}]}"
(just before the header":{"type":"rum"}
section)
"{\"asset_identification\":{\"asset\":{\"name\":\"regid.2019-10.com.cisco.C8000V,1.0_e361c3dc-27c2-4084-b4a4-cae639cff335\"},\"instance\":{\"sudi\":{\"udi_pid\":\"C8000V\",\"udi_serial_number\":\"abcdef123456\"}},\"signature\":{\"signing_type\":\"builtin\",\"key\":\"regid.2019-10.com.cisco.C8000V,1.0_e361c3dc-27c2-4084-b4a4-cae639cff335\",\"value\":\"abcdef123456\"}},\"meta\":{\"entitlement_tag\":\"regid.2018-12.com.cisco.DNA_P_50M_A,1.0_100fb8b2-f5cc-459c-9253-ac77b827fd71\",\"report_id\":1646687408,\"software_version\":\"17.06.02\",\"ha_udi\":[{\"role\":\"Active\",\"sudi\":{\"udi_pid\":\"C8000V\",\"udi_serial_number\":\"abcdef123456\"}}]},\"measurements\":[{\"log_time\":1657549482,\"metric_name\":\"ENTITLEMENT\",\"start_time\":1657549046,\"end_time\":1657550382,\"sample_interval\":1336,\"num_samples\":2,\"meta\":{\"termination_reason\":\"CurrentUsageRequested\"},\"value\":{\"type\":\"COUNT\",\"value\":\"1\"}}]}"
Within the same usage report, copy the key
& value
fields under the signature
section - and add to the Postman environment variables usage_signature_key
& usage_signature_value
signature
section is the last item in the usage report payload"signature":{"sudi":{"udi_pid":"C8000V","udi_serial_number":"ABCD12345"},"signing_type":"builtin","key":"<usage_signature_key>","value":"<usage_signature_value>"}
Run the Postman request: License Reservation
> 05 - Report License Usage
Similar to Step 3, the response will be a poll_id
that we can use to check the status of the report
[Step 6] Check License Usage Report Status
License Reservation
> 04 & 06 - Check License Request / Obtain License / Get License ACK
status
of COMPLETE
smart_license
field
license smart import <bootflash|tftp>:ACK.txt
show license status
[OPTIONAL] Return a License / Remove Device
license smart authorization return local online
remove_code
License Return
> 03 - Remove License
poll_id
to check task statusLicense Return
> 04 - Check Removal Request
status
of COMPLETE
[OPTIONAL] Check License Inventory / Validate License Consumption
License Verification
> 03 - Get License Usage by Tag
tags
list to query only specific licensesThis request can be used to look up the required ISO 19770-2 license tag for other requests
Alternatively, we can query a list of all devices in our Virtual Account - and see which devices have licenses assigned:
License Verification
> 03a - Get Devices & License Assignment
This request will query ALL devices in a Virtual account & display details on device identifiers (PID, SN, Name, etc) and any licenses assigned.
The included Python scripts follow the same order as the Postman collection steps above, but are simplified since we can automate a lot of the background tasks (like collecting auth tokens & SA/VA IDs).
[Step 1] Generate License Reservation
01 - reserve license.py
lic.txt
license smart import <bootflash|tftp>:lic.txt
[Step 2] Upload Usage Report & Download ACK
license smart save usage all file <bootflash|tftp>:<filename>
usage.txt
02 - report license usage.py
ack.txt
license smart import <bootflash|tftp>:ACK.txt
[OPTIONAL] Return a License / Remove Device
license smart authorization return local online
03 - remove license.py
All screenshots below are from the Python script execution & reserving a DNA-HSEC license for a Catalyst 8000V router.
Example of license reservation:
Example of license usage report:
Example of license removal:
Provided under Cisco Sample Code License, for details see LICENSE
Our code of conduct is available here
See our contributing guidelines here
Please note: This script is meant for demo purposes only. All tools/ scripts in this repo are released for use "AS IS" without any warranties of any kind, including, but not limited to their installation, use, or performance. Any use of these scripts and tools is at your own risk. There is no guarantee that they have been through thorough testing in a comparable environment and we are not responsible for any damage or data loss incurred with their use.
You are responsible for reviewing and testing any scripts you run thoroughly before use in any non-testing environment.
Owner
Contributors
Categories
Programming Languages
PythonLicense
Code Exchange Community
Get help, share code, and collaborate with other developers in the Code Exchange community.View Community