Skip to content

Commit 1f09c19

Browse files
author
GVE Devnet Admin
committed
Baselined from internal Repository
last_commit:3505ebe869aa9d23f5d59ac5c9cbf4a16b3a7ef4
0 parents  commit 1f09c19

File tree

9 files changed

+540
-0
lines changed

9 files changed

+540
-0
lines changed

CODE_OF_CONDUCT.md

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Code of Conduct
2+
3+
## Our Pledge
4+
5+
In the interest of fostering an open and welcoming environment, we as maintainers of this Cisco Sample Code pledge to making participation with our project a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6+
7+
## Our Standards
8+
9+
Examples of behavior that contributes to creating a positive environment include:
10+
11+
* Using welcoming and inclusive language
12+
* Being respectful of differing viewpoints and experiences
13+
* Gracefully accepting constructive criticism
14+
* Showing empathy towards other people
15+
16+
Examples of unacceptable behavior include:
17+
18+
* The use of sexualized language or imagery and unwelcome sexual attention or advances
19+
* Trolling, insulting/derogatory comments, and personal or political attacks
20+
* Public or private harassment
21+
* Publishing others' private information, such as a physical or electronic address, without explicit permission
22+
* Other conduct which could reasonably be considered inappropriate in a professional setting
23+
24+
## Our Responsibilities
25+
26+
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
27+
28+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other interactions with this project that are not aligned to this Code of Conduct, or to ban temporarily or permanently any person for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
29+
30+
## Scope
31+
32+
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project. Examples of representing a project include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
33+
34+
## Enforcement
35+
36+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the Cisco SE GitHub team at [email protected]. The team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
37+
38+
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project or Cisco SE Leadership.
39+
40+
## Attribution
41+
42+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
43+
44+
[homepage]: http://contributor-covenant.org
45+
[version]: http://contributor-covenant.org/version/1/4/

CONTRIBUTING.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Cisco Sample Code
2+
3+
This project, and the code contained herein, is provided for example and/or demonstration purposes by Cisco for use by our partners and customers in working with Cisco's products and services. While Cisco's customers and partners are free to use this code pursuant to the terms set forth in the [LICENSE][LICENSE], this is not an Open Source project as we are not seeking to build a community around this project and its capabilities.
4+
5+
6+
We do desire to provide functional and high-quality examples and demonstrations. If you should discover some bug, issue, or opportunity for enhancement with the code contained in this project, please do notify us by:
7+
8+
1. **Reviewing Open Issues** to verify that the issue hasn't already been reported.
9+
2. **Opening a New Issue** to report the bug, issue, or enhancement opportunity.
10+
11+
[LICENSE]: ../LICENSE

Connection.py

+206
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
from prettyprinter import pprint
2+
from genie.testbed import load
3+
from unicon.eal.dialogs import Dialog, Statement
4+
5+
6+
# Function to handle the prompt
7+
def handle_destination_prompt(spawn, session, context):
8+
spawn.sendline('') # Sending an empty line as response to accept the default
9+
10+
11+
class PYATSConnection:
12+
def __init__(self):
13+
self.__testbed = load("./res/testbeds/testbed.yaml")
14+
15+
def get_device_by_role(self, role):
16+
"""
17+
Retrieves a list of devices that match a specific role from the testbed.
18+
This function filters devices based on their assigned role attribute, useful for targeting specific types of devices in network scripts.
19+
"""
20+
return [device for device in self.__testbed.devices.values() if device.role == role]
21+
22+
def __find_device_by_ip(self, ip):
23+
"""
24+
Searches for and returns a device object based on its IP address.
25+
This function iterates through all devices in the testbed, checking each one's SSH connection IP address against the provided IP.
26+
"""
27+
for device_name, device in self.__testbed.devices.items():
28+
if ip == str(device.connections['ssh']['ip']):
29+
return device
30+
31+
return None
32+
33+
def get_device_running_config(self, device):
34+
"""
35+
Connects to a specified device and retrieves its running configuration using the learn('config') method from PyATS,
36+
which abstracts and structures the device's configuration.
37+
"""
38+
if device is not None:
39+
pprint(type(device))
40+
device.connect(init_config_commands=[])
41+
return device.learn('config')
42+
else:
43+
return None
44+
45+
def search_and_replace_device_running_config(self, device, search="ip tacacs source-interface Vlan1"):
46+
"""
47+
Searches for a specific configuration line within a device's running configuration and replaces it if found.
48+
It demonstrates modifying device configurations programmatically, such as changing TACACS source interface settings.
49+
"""
50+
if device is not None:
51+
device.connect(init_config_commands=[])
52+
output = device.execute(f'show run | include {search}')
53+
print(f"output of {search}: {output}")
54+
if search in output:
55+
# Unconfigure the old source interface and configure the new one
56+
device.configure('no ip tacacs source-interface Vlan1')
57+
device.configure('ip tacacs source-interface Vlan128')
58+
else:
59+
return None
60+
61+
def search_device_trunk_interfaces(self, device):
62+
"""
63+
Examines a device for trunk interfaces and adjusts VLAN settings on those trunks.
64+
It also provides an example of how to parse and modify interface configurations based on operational and administrative criteria.
65+
"""
66+
if device is not None:
67+
device.connect(init_config_commands=[])
68+
interfaces = device.parse('show interfaces switchport')
69+
for interface_name, interface_data in interfaces.items():
70+
operational_mode = interface_data.get("operational_mode", "")
71+
administrative_mode = interface_data.get("switchport_mode", "")
72+
if operational_mode == "trunk" and administrative_mode == "trunk":
73+
vlan_list = []
74+
trunk_vlans = interface_data.get('trunk_vlans', '')
75+
# Handle VLAN ranges like "800-900"
76+
for vlan_range in trunk_vlans.split(','):
77+
if '-' in vlan_range:
78+
start_vlan, end_vlan = vlan_range.split('-')
79+
vlan_list.extend(range(int(start_vlan), int(end_vlan) + 1))
80+
else:
81+
if vlan_range:
82+
if vlan_range != "all":
83+
vlan_list.append(int(vlan_range))
84+
85+
config_commands = [f"interface {interface_name}"]
86+
87+
# Check if VLAN 128 is in the list
88+
print(f"{interface_name} VLAN LIST: {vlan_list}")
89+
90+
if 128 not in vlan_list:
91+
config_commands += [
92+
"switchport trunk allowed vlan add 128"
93+
]
94+
if 1 in vlan_list:
95+
config_commands += [
96+
"switchport trunk allowed vlan remove 1"
97+
]
98+
if len(config_commands) > 1:
99+
print(config_commands)
100+
device.configure(config_commands)
101+
else:
102+
return None
103+
104+
def change_trunking_encapsulation_vlan(self, device, current_vlan: int, updated_vlan: int):
105+
"""
106+
Examines a device for trunk interfaces and adjusts VLAN settings on those trunks.
107+
It also provides an example of how to parse and modify interface configurations based on operational and administrative criteria.
108+
"""
109+
if device is not None:
110+
device.connect(init_config_commands=[])
111+
interfaces = device.parse('show ip interface brief')
112+
for interface_name, interface_data in interfaces["interface"].items():
113+
print(interface_name)
114+
if "." in interface_name:
115+
interface_details = device.parse(f'show interface {interface_name}')
116+
if interface_details[interface_name]['encapsulations']['encapsulation'] == "dot1q" and int(
117+
interface_details[interface_name]['encapsulations']['first_dot1q']) == current_vlan:
118+
config_commands = [f"interface {interface_name}", f"encapsulation dot1Q {updated_vlan} native"]
119+
device.configure(config_commands)
120+
121+
def update_device_access_vlans_on_interfaces(self, device, current_access_vlan: int, updated_access_vlan: int):
122+
"""
123+
Updates the access VLANs on all interfaces of a device that are set to a specific VLAN.
124+
This function can be crucial in network migrations or reconfigurations where VLAN changes are common.
125+
"""
126+
if device is not None:
127+
device.connect(init_config_commands=[])
128+
interfaces = device.parse('show interfaces switchport')
129+
for interface_name, interface_data in interfaces.items():
130+
operational_mode = interface_data.get("operational_mode", "")
131+
administrative_mode = interface_data.get("switchport_mode", "")
132+
print(interface_data)
133+
input()
134+
if operational_mode == "static access" or operational_mode == "down": # ACCESS, DOWN, TRUNK
135+
if administrative_mode == "static access": # TRUNK OR ACCESS
136+
access_vlan = interface_data['access_vlan']
137+
if current_access_vlan == int(access_vlan):
138+
config_commands = [f'interface {interface_name}',
139+
f"switchport access vlan {updated_access_vlan}",
140+
f"authentication event server dead action reinitialize vlan {updated_access_vlan}"]
141+
device.configure(config_commands)
142+
143+
def save_current_config(self, device, date):
144+
"""
145+
Saves the current configuration of the device to its local storage.
146+
This function includes handling for prompts that may appear during the save process,
147+
making it robust for automated scripts.
148+
"""
149+
if device is not None:
150+
# Create the dialog
151+
dialog = Dialog([
152+
Statement(pattern=r'Destination filename \[(.*)\]\?',
153+
action=handle_destination_prompt,
154+
loop_continue=True,
155+
continue_timer=False)
156+
])
157+
158+
device.connect(init_config_commands=[])
159+
device.execute(f"copy run flash:sh-run-{date}.txt", reply=dialog)
160+
161+
162+
def update_svi(self, device, svi_interface, updated_svi_interface):
163+
"""
164+
Copies the configuration from one switched virtual interface (SVI) to another and shuts down the original SVI.
165+
This function demonstrates advanced manipulation of interface configurations,
166+
useful for significant network restructurings or consolidations.
167+
"""
168+
if device is not None:
169+
device.connect(init_config_commands=[])
170+
# Execute command to get the configuration for the specified SVI interface
171+
output = device.execute(f'show run interface {svi_interface}')
172+
173+
# Initialize a list to hold the configuration commands
174+
config_commands = []
175+
capturing = False
176+
177+
# Process each line in the output to capture the relevant configuration
178+
for line in output.splitlines():
179+
# Check if the current line is the start of the interface configuration
180+
if line.strip().startswith(f"interface {svi_interface}"):
181+
capturing = True
182+
continue # Skip adding the interface declaration line itself
183+
184+
# Check if we are currently capturing and if the line is not a sub-interface or another main interface
185+
if capturing and line.startswith(' interface'):
186+
break # Stop capturing on encountering a new interface definition
187+
188+
# If capturing, add the line to our commands list
189+
if capturing:
190+
config_commands.append(line.strip())
191+
192+
#Default the old interface
193+
shutdown_interface_commands = [f"default interface {svi_interface}",f"interface {svi_interface}", f"shut"]
194+
device.configure(shutdown_interface_commands)
195+
# Prepare the new interface configuration commands
196+
new_interface_commands = [f"interface {updated_svi_interface}"] + config_commands
197+
198+
# Apply configuration to the new interface
199+
try:
200+
device.configure(new_interface_commands)
201+
print(f"Configuration successfully applied to {updated_svi_interface}")
202+
except Exception as e:
203+
print(f"Error during configuration transfer: {str(e)}")
204+
205+
206+

IMAGES/0image.png

48.8 KB
Loading

LICENSE.md

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
CISCO SAMPLE CODE LICENSE
2+
Version 1.1
3+
Copyright (c) 2022 Cisco and/or its affiliates
4+
5+
These terms govern this Cisco Systems, Inc. ("Cisco"), example or demo
6+
source code and its associated documentation (together, the "Sample
7+
Code"). By downloading, copying, modifying, compiling, or redistributing
8+
the Sample Code, you accept and agree to be bound by the following terms
9+
and conditions (the "License"). If you are accepting the License on
10+
behalf of an entity, you represent that you have the authority to do so
11+
(either you or the entity, "you"). Sample Code is not supported by Cisco
12+
TAC and is not tested for quality or performance. This is your only
13+
license to the Sample Code and all rights not expressly granted are
14+
reserved.
15+
16+
1. LICENSE GRANT: Subject to the terms and conditions of this License,
17+
Cisco hereby grants to you a perpetual, worldwide, non-exclusive, non-
18+
transferable, non-sublicensable, royalty-free license to copy and
19+
modify the Sample Code in source code form, and compile and
20+
redistribute the Sample Code in binary/object code or other executable
21+
forms, in whole or in part, solely for use with Cisco products and
22+
services. For interpreted languages like Java and Python, the
23+
executable form of the software may include source code and
24+
compilation is not required.
25+
26+
2. CONDITIONS: You shall not use the Sample Code independent of, or to
27+
replicate or compete with, a Cisco product or service. Cisco products
28+
and services are licensed under their own separate terms and you shall
29+
not use the Sample Code in any way that violates or is inconsistent
30+
with those terms (for more information, please visit:
31+
www.cisco.com/go/terms).
32+
33+
3. OWNERSHIP: Cisco retains sole and exclusive ownership of the Sample
34+
Code, including all intellectual property rights therein, except with
35+
respect to any third-party material that may be used in or by the
36+
Sample Code. Any such third-party material is licensed under its own
37+
separate terms (such as an open source license) and all use must be in
38+
full accordance with the applicable license. This License does not
39+
grant you permission to use any trade names, trademarks, service
40+
marks, or product names of Cisco. If you provide any feedback to Cisco
41+
regarding the Sample Code, you agree that Cisco, its partners, and its
42+
customers shall be free to use and incorporate such feedback into the
43+
Sample Code, and Cisco products and services, for any purpose, and
44+
without restriction, payment, or additional consideration of any kind.
45+
If you initiate or participate in any litigation against Cisco, its
46+
partners, or its customers (including cross-claims and counter-claims)
47+
alleging that the Sample Code and/or its use infringe any patent,
48+
copyright, or other intellectual property right, then all rights
49+
granted to you under this License shall terminate immediately without
50+
notice.
51+
52+
4. LIMITATION OF LIABILITY: CISCO SHALL HAVE NO LIABILITY IN CONNECTION
53+
WITH OR RELATING TO THIS LICENSE OR USE OF THE SAMPLE CODE, FOR
54+
DAMAGES OF ANY KIND, INCLUDING BUT NOT LIMITED TO DIRECT, INCIDENTAL,
55+
AND CONSEQUENTIAL DAMAGES, OR FOR ANY LOSS OF USE, DATA, INFORMATION,
56+
PROFITS, BUSINESS, OR GOODWILL, HOWEVER CAUSED, EVEN IF ADVISED OF THE
57+
POSSIBILITY OF SUCH DAMAGES.
58+
59+
5. DISCLAIMER OF WARRANTY: SAMPLE CODE IS INTENDED FOR EXAMPLE PURPOSES
60+
ONLY AND IS PROVIDED BY CISCO "AS IS" WITH ALL FAULTS AND WITHOUT
61+
WARRANTY OR SUPPORT OF ANY KIND. TO THE MAXIMUM EXTENT PERMITTED BY
62+
LAW, ALL EXPRESS AND IMPLIED CONDITIONS, REPRESENTATIONS, AND
63+
WARRANTIES INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTY OR
64+
CONDITION OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-
65+
INFRINGEMENT, SATISFACTORY QUALITY, NON-INTERFERENCE, AND ACCURACY,
66+
ARE HEREBY EXCLUDED AND EXPRESSLY DISCLAIMED BY CISCO. CISCO DOES NOT
67+
WARRANT THAT THE SAMPLE CODE IS SUITABLE FOR PRODUCTION OR COMMERCIAL
68+
USE, WILL OPERATE PROPERLY, IS ACCURATE OR COMPLETE, OR IS WITHOUT
69+
ERROR OR DEFECT.
70+
71+
6. GENERAL: This License shall be governed by and interpreted in
72+
accordance with the laws of the State of California, excluding its
73+
conflict of laws provisions. You agree to comply with all applicable
74+
United States export laws, rules, and regulations. If any provision of
75+
this License is judged illegal, invalid, or otherwise unenforceable,
76+
that provision shall be severed and the rest of the License shall
77+
remain in full force and effect. No failure by Cisco to enforce any of
78+
its rights related to the Sample Code or to a breach of this License
79+
in a particular situation will act as a waiver of such rights. In the
80+
event of any inconsistencies with any other terms, this License shall
81+
take precedence.

0 commit comments

Comments
 (0)