Skip to content

Commit

Permalink
template
Browse files Browse the repository at this point in the history
  • Loading branch information
nickrusso42518 committed Oct 15, 2023
1 parent d561a82 commit 7c2c2e1
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 0 deletions.
127 changes: 127 additions & 0 deletions enauto3/m4a/05_build_templ.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#!/usr/bin/env python

"""
Author: Nick Russo
Purpose: Add required loopback0 configuration to support the SDA fabric.
"""

import json
from dnac_requester import DNACRequester


def main():
"""
Execution begins here.
"""

# Create a DNARequester object with our sandbox parameters
# Can use DevNet reservable instance (10.10.20.85) or dCloud HW sandbox
# https://dcloud.cisco.com
dnac = DNACRequester(
# host="10.10.20.85", username="admin", password="Cisco1234!", verify=False
host="198.18.129.100",
username="admin",
password="C1sco12345",
verify=False,
)

# Build a new project using a name and description
proj_body = {
"name": "sda_proj",
"description": "setup device for SDA",
}
proj_resp = dnac.req(
"dna/intent/api/v1/template-programmer/project",
method="post",
jsonbody=proj_body,
)

# Wait for the project to get completed, then extract the project ID
proj_task = dnac.wait_for_task(proj_resp.json()["response"]["taskId"])
proj_id = proj_task.json()["response"]["data"]

with open("input_data/template.json", "r") as handle:
temp_data = json.load(handle)

# Issue POST request to build a template into existing project
# using template data just loaded from JSON file
print("Creating template")
temp_resp = dnac.req(
f"dna/intent/api/v1/template-programmer/project/{proj_id}/template",
method="post",
jsonbody=temp_data,
)

# Wait for task to finish, and capture the "data" value, which is
# the template ID
temp_task = dnac.wait_for_task(temp_resp.json()["response"]["taskId"])
temp_id = temp_task.json()["response"]["data"]

# Start a simulation (aka preview) to render the template. First,
# build the body by combining the sample variables and template ID
prev_body = {"params": {"lb0_ip": "203.0.113.9"}, "templateId": temp_id}

# Then, issue the HTTP PUT request to begin the previous without
# raising an HTTPError if the status code >= 400
prev_data = dnac.req(
"dna/intent/api/v1/template-programmer/template/preview",
method="put",
jsonbody=prev_body,
).json()

# If any validation errors exist, print them out. These include using the
# wrong data type, omitted required variables, wrong template IDs, etc
if prev_data["validationErrors"]:
print("Errors:")
for error in prev_data["validationErrors"]:
print(f"{error['type']}: {error['message']}")

# The simulation succeeded, so print the rendered text after
# variable substitution has taken place
else:
print("Snippet rendered:")
print(prev_data["cliPreview"])

# Apply the template on a test Cat9300 switch
version_and_deploy(dnac, temp_id)


def version_and_deploy(dnac, temp_id):
"""
Helper function to version and deploy the templates as they are rendered.
This should only be called when the template renders successfully (ie,
without errors). This issues the "version" and "deploy" API calls to
a sample IP address specified. If ip_addr is not specified, it defaults
to leaf1 in the DevNet DNA Center reservable sandbox (this may change).
"""

# Version (commit) template. You must do this before trying to deploy
# the template
ver_body = {"comments": "initial commit via API", "templateId": temp_id}
ver_resp = dnac.req(
"dna/intent/api/v1/template-programmer/template/version",
method="post",
jsonbody=ver_body,
)
ver_task = dnac.wait_for_task(ver_resp.json()["response"]["taskId"])
print(f"Version status: {ver_task.json()['response']['progress']}")

# Load the template deployment body and update the templateId value
with open("input_data/push_temp.json", "r") as handle:
deploy_body = json.load(handle)
deploy_body["templateId"] = temp_id

# Deploy (apply) template. The body is similar to the preview body
# except we must specify targets to configure. This is a list of
# dictionaries, allowing for bulk deployment. To keep it simple,
# you can hardcode a single IP address or UUID into the "id" field
deploy_resp = dnac.req(
"dna/intent/api/v1/template-programmer/template/deploy",
method="post",
jsonbody=deploy_body,
)
print(f"Deploy status: {deploy_resp.json()['deploymentId']}")


if __name__ == "__main__":
main()
27 changes: 27 additions & 0 deletions enauto3/m4a/input_data/push_temp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"forcePushTemplate": true,
"targetInfo": [
{
"id": "198.18.128.22",
"params": {
"lb0_ip": "192.0.2.22"
},
"type": "MANAGED_DEVICE_IP"
},
{
"id": "198.18.128.23",
"params": {
"lb0_ip": "192.0.2.23"
},
"type": "MANAGED_DEVICE_IP"
},
{
"id": "198.18.128.24",
"params": {
"lb0_ip": "192.0.2.24"
},
"type": "MANAGED_DEVICE_IP"
}
],
"templateId": "change_me"
}
21 changes: 21 additions & 0 deletions enauto3/m4a/input_data/template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "sda_temp",
"composite": false,
"deviceTypes": [
{
"productFamily": "Switches and Hubs",
"productSeries": "Cisco Catalyst 9300 Series Switches",
"productType": "Cisco Catalyst 9300 Switch"
}
],
"softwareType": "IOS-XE",
"templateContent": "interface Loopback0\nip address $lb0_ip 255.255.255.255",
"templateParams": [
{
"parameterName": "$lb0_ip",
"dataType": "STRING",
"required": true,
"order": 1
}
]
}

0 comments on commit 7c2c2e1

Please sign in to comment.