From 47553c43d71b7b1144f912ab9679f5b60e858fa2 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 11 May 2023 11:04:53 +0200 Subject: Adding upstream version 1.3.1+dfsg. Signed-off-by: Daniel Baumann --- .../atd_e2e_provisioning_workflow.py | 120 +++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 docs/labs/lab06-provisioning/atd_e2e_provisioning_workflow.py (limited to 'docs/labs/lab06-provisioning/atd_e2e_provisioning_workflow.py') diff --git a/docs/labs/lab06-provisioning/atd_e2e_provisioning_workflow.py b/docs/labs/lab06-provisioning/atd_e2e_provisioning_workflow.py new file mode 100644 index 0000000..8d4445f --- /dev/null +++ b/docs/labs/lab06-provisioning/atd_e2e_provisioning_workflow.py @@ -0,0 +1,120 @@ +# Copyright (c) 2021 Arista Networks, Inc. +# Use of this source code is governed by the Apache License 2.0 +# that can be found in the COPYING file. + +# This script is an example on provisioning registered devices in CloudVision that is based on +# Arista Test Drive (ATD) and similar to what the ansible playbooks do in +# https://github.com/arista-netdevops-community/atd-avd. +# It does the following: +# - creates and uploads configlets, +# - creates the container hierarchy in Network Provisiong +# - moves the devices to their target containers +# - assigns the configlets to the devices +# - creates a change control from the genereated tasks +# - approves and executes the change control + +import uuid +import time +import ssl +from datetime import datetime +from cvprac.cvp_client import CvpClient +ssl._create_default_https_context = ssl._create_unverified_context + +# Create connection to CloudVision +clnt = CvpClient() +clnt.connect(['cvp1'],'username', 'password') + +# Create container topology +container_name = "DC1_LEAFS" +container_topology = [{"containerName": "ATD_FABRIC", "parentContainerName": 'Tenant'}, + {"containerName": "ATD_LEAFS", "parentContainerName": 'ATD_FABRIC'}, + {"containerName": "pod1", "parentContainerName": 'ATD_LEAFS'}, + {"containerName": "pod2", "parentContainerName": 'ATD_LEAFS'}, + {"containerName": "ATD_SERVERS", "parentContainerName": 'ATD_FABRIC'}, + {"containerName": "ATD_SPINES", "parentContainerName": 'ATD_FABRIC'}, + {"containerName": "ATD_TENANT_NETWORKS", "parentContainerName": 'ATD_FABRIC'}] +for container in container_topology: + try: + container_name = container['containerName'] + # Get parent container information + parent = clnt.api.get_container_by_name(container['parentContainerName']) + print(f'Creating container {container_name}\n') + clnt.api.add_container(container_name,parent["name"],parent["key"]) + except Exception as e: + if "Data already exists in Database" in str(e): + print ("Container already exists, continuing...") + +# Create device mappers +devices = [{'deviceName': "leaf1", + 'configlets': ["BaseIPv4_Leaf1", "AVD_leaf1"], + "parentContainerName": "pod1"}, + {'deviceName': "leaf2", + 'configlets': ["BaseIPv4_Leaf2", "AVD_leaf2"], + "parentContainerName": "pod1"}, + {'deviceName': "leaf3", + 'configlets': ["BaseIPv4_Leaf3", "AVD_leaf3"], + "parentContainerName": "pod2"}, + {'deviceName': "leaf4", + 'configlets': ["BaseIPv4_Leaf4", "AVD_leaf4"], + "parentContainerName": "pod2"}, + {'deviceName': "spine1", + 'configlets': ["BaseIPv4_Spine1", "AVD_spine1"], + "parentContainerName": "ATD_SPINES"}, + {'deviceName': "spine2", + 'configlets': ["BaseIPv4_Spine2", "AVD_spine2"], + "parentContainerName": "ATD_SPINES"}] + +task_list = [] +for device in devices: + # Load the AVD configlets from file + with open("./configlets/AVD_" + device['deviceName'] + ".cfg", "r") as file: + configlet_file = file.read() + avd_configlet_name = device['configlets'][1] + base_configlet_name = device['configlets'][0] # preloaded configlet in an ATD environment + container_name = device['parentContainerName'] + base_configlet = clnt.api.get_configlet_by_name(base_configlet_name) + configlets = [base_configlet] + # Update the AVD configlets if they exist, otherwise upload them from the configlets folder + print (f"Creating configlet {avd_configlet_name} for {device['deviceName']}\n") + try: + configlet = clnt.api.get_configlet_by_name(avd_configlet_name) + clnt.api.update_configlet(configlet_file, configlet['key'], avd_configlet_name) + configlets.append(configlet) + except: + clnt.api.add_configlet(avd_configlet_name, configlet_file) + configlet = clnt.api.get_configlet_by_name(avd_configlet_name) + configlets.append(configlet) + # Get device data + device_data = clnt.api.get_device_by_name(device['deviceName'] + ".atd.lab") + # Get the parent container data for the device + container = clnt.api.get_container_by_name(container_name) + device_name = device['deviceName'] + print(f"Moving device {device_name} to container {container_name}\n") + # The move action will create the task first, however if the devices are already in the target + # container, for instance if the script was run multiple times than the move action will + # not generate a task anymore, therefore it's better to create the task list from the + # Update Config action which will reuse the Move Device action's task if one exists, + # otherwise will create a new one. + move = clnt.api.move_device_to_container("python", device_data, container) + apply_configlets = clnt.api.apply_configlets_to_device("", device_data, configlets) + task_list = task_list + apply_configlets['data']['taskIds'] + +print(f"Generated task IDs are: {task_list}\n") + +# Generate unique ID for the change control +cc_id = str(uuid.uuid4()) +cc_name = f"Change_{datetime.now().strftime('%Y%m%d_%H%M%S')}" + +print("Creating Change control with the list of tasks") +clnt.api.change_control_create_for_tasks(cc_id, cc_name, task_list, series=False) + +print("Approving Change Control") +# adding a few seconds sleep to avoid small time diff between the local system and CVP +time.sleep(2) +approve_note = "Approving CC via cvprac" +clnt.api.change_control_approve(cc_id, notes=approve_note) + +# Start the change control +print("Executing Change Control...") +start_note = "Start the CC via cvprac" +clnt.api.change_control_start(cc_id, notes=start_note) -- cgit v1.2.3