diff --git a/topologies/training-level1-me/atd-topo.png b/topologies/training-level1-me/atd-topo.png new file mode 100644 index 000000000..66e36d4d5 Binary files /dev/null and b/topologies/training-level1-me/atd-topo.png differ diff --git a/topologies/training-level1-me/configlets/ATD-INFRA b/topologies/training-level1-me/configlets/ATD-INFRA new file mode 100644 index 000000000..6a88951d1 --- /dev/null +++ b/topologies/training-level1-me/configlets/ATD-INFRA @@ -0,0 +1,45 @@ +daemon TerminAttr + exec /usr/bin/TerminAttr -cvcompression=gzip -smashexcludes=ale,flexCounter,hardware,kni,pulse,strata -ingestexclude=/Sysdb/cell/1/agent,/Sysdb/cell/2/agent -cvaddr=192.168.0.5:9910 -cvauth=token,/tmp/token -cvvrf=default -taillogs -disableaaa + no shutdown +! +alias mlag-reload bash /mnt/flash/shut_intfs && sudo shutdown now -r +alias conint sh interface | i connected +alias senz show interface counter error | nz +alias shmc show int | awk '/^[A-Z]/ { intf = $1 } /, address is/ { print intf, $6 }' +alias snz show interface counter | nz +alias spd show port-channel %1 detail all +alias sqnz show interface counter queue | nz +alias srnz show interface counter rate | nz +alias intdesc + !! Usage: intdesc interface-name description + 10 config + 20 int %1 + 30 desc %2 + 40 exit +! +dns domain arista.lab +! +service routing protocols model multi-agent +! +ntp server 192.168.0.1 iburst source Management1 +! +radius-server host 192.168.0.1 key 7 0207165218120E +! +aaa group server radius atds + server 192.168.0.1 +! +aaa authentication login default group atds local +aaa authorization exec default group atds local +aaa authorization commands all default local +! +username Script secret sha512 $6$PNfpb9anSBQ5/aia$phaa3ar5pwkntenD9WHc6Ed5b96lbW0dc0bjtwPnFLaDiCK8D5Cjl6ewP/xdNbl4PtS6Paq.3SssN8pj05NQm. +username admin privilege 15 role network-admin secret 5 $1$5O85YVVn$HrXcfOivJEnISTMb6xrJc. +username arista privilege 15 role network-admin secret 5 $1$4VjIjfd1$XkUVulbNDESHFzcxDU.Tk1 +! +username arista ssh-key ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+ERvV4GaPq3FzxY8T+5hMF/1T+l8wiPsVCtOrZU4Hy6NCNlAiDBdA/RUtX5/aOu5JvHyPTVHqWJ0qi9BqU3rxCNl/l2/5UZbm9RPzdZ1QCwoYwPB9/j/tYJV8lZdr6t0yGBfxgzD3oW/zF7a+ZtASaMAu7lkgoqPK2pVIGa+Y9ZCsA0Xq756XpLCw+d3pHKHvIkgWLCo9FoeIv8f/bu5u/ztzRE+Nvl+o5add6MxnjsXz3s7BnW2FX6JNjyp0Z+OXjupQc2gcfFvpd/dA2lCNuuaCHkRgyPwIZtWPmNqMRXPp37mlPwV43qDJRVPQkvh0xPxwS35BbzUxWdT+ZLZv +! +ip radius source-interface Management1 +! +management api http-commands + no shutdown +! diff --git a/topologies/training-level1-me/configlets/host1-base b/topologies/training-level1-me/configlets/host1-base new file mode 100644 index 000000000..f67ef5a60 --- /dev/null +++ b/topologies/training-level1-me/configlets/host1-base @@ -0,0 +1,11 @@ +hostname host1 +! +interface Management 1 + ip address 192.168.0.51/24 + no lldp transmit + no lldp receive +! +ip route 0.0.0.0/0 192.168.0.1 +! +ip routing +! diff --git a/topologies/training-level1-me/configlets/host2-base b/topologies/training-level1-me/configlets/host2-base new file mode 100644 index 000000000..526946918 --- /dev/null +++ b/topologies/training-level1-me/configlets/host2-base @@ -0,0 +1,11 @@ +hostname host2 +! +interface Management 1 + ip address 192.168.0.52/24 + no lldp transmit + no lldp receive +! +ip route 0.0.0.0/0 192.168.0.1 +! +ip routing +! diff --git a/topologies/training-level1-me/configlets/leaf1-base b/topologies/training-level1-me/configlets/leaf1-base new file mode 100644 index 000000000..39b184ff8 --- /dev/null +++ b/topologies/training-level1-me/configlets/leaf1-base @@ -0,0 +1,13 @@ +hostname leaf1 +! +interface Management 1 + ip address 192.168.0.21/24 + no lldp transmit + no lldp receive +! +service routing protocols model multi-agent +! +ip route 0.0.0.0/0 192.168.0.1 +! +ip routing +! diff --git a/topologies/training-level1-me/configlets/leaf2-base b/topologies/training-level1-me/configlets/leaf2-base new file mode 100644 index 000000000..a4de43f34 --- /dev/null +++ b/topologies/training-level1-me/configlets/leaf2-base @@ -0,0 +1,13 @@ +hostname leaf2 +! +interface Management 1 + ip address 192.168.0.22/24 + no lldp transmit + no lldp receive +! +service routing protocols model multi-agent +! +ip route 0.0.0.0/0 192.168.0.1 +! +ip routing +! diff --git a/topologies/training-level1-me/configlets/leaf3-base b/topologies/training-level1-me/configlets/leaf3-base new file mode 100644 index 000000000..e6ebd98cc --- /dev/null +++ b/topologies/training-level1-me/configlets/leaf3-base @@ -0,0 +1,13 @@ +hostname leaf3 +! +interface Management 1 + ip address 192.168.0.23/24 + no lldp transmit + no lldp receive +! +service routing protocols model multi-agent +! +ip route 0.0.0.0/0 192.168.0.1 +! +ip routing +! diff --git a/topologies/training-level1-me/configlets/leaf4-base b/topologies/training-level1-me/configlets/leaf4-base new file mode 100644 index 000000000..95c53c26c --- /dev/null +++ b/topologies/training-level1-me/configlets/leaf4-base @@ -0,0 +1,13 @@ +hostname leaf4 +! +interface Management 1 + ip address 192.168.0.24/24 + no lldp transmit + no lldp receive +! +service routing protocols model multi-agent +! +ip route 0.0.0.0/0 192.168.0.1 +! +ip routing +! diff --git a/topologies/training-level1-me/configlets/spine1-base b/topologies/training-level1-me/configlets/spine1-base new file mode 100644 index 000000000..66d5d9280 --- /dev/null +++ b/topologies/training-level1-me/configlets/spine1-base @@ -0,0 +1,13 @@ +hostname spine1 +! +interface Management 1 + ip address 192.168.0.11/24 + no lldp transmit + no lldp receive +! +service routing protocols model multi-agent +! +ip route 0.0.0.0/0 192.168.0.1 +! +ip routing +! diff --git a/topologies/training-level1-me/configlets/spine2-base b/topologies/training-level1-me/configlets/spine2-base new file mode 100644 index 000000000..15ba31a64 --- /dev/null +++ b/topologies/training-level1-me/configlets/spine2-base @@ -0,0 +1,13 @@ +hostname spine2 +! +interface Management 1 + ip address 192.168.0.12/24 + no lldp transmit + no lldp receive +! +service routing protocols model multi-agent +! +ip route 0.0.0.0/0 192.168.0.1 +! +ip routing +! diff --git a/topologies/training-level1-me/files/.ansible.cfg b/topologies/training-level1-me/files/.ansible.cfg new file mode 100644 index 000000000..14c806515 --- /dev/null +++ b/topologies/training-level1-me/files/.ansible.cfg @@ -0,0 +1,2 @@ +[defaults] +host_key_checking = False diff --git a/topologies/training-level1-me/files/.screenrc b/topologies/training-level1-me/files/.screenrc new file mode 100644 index 000000000..76c394214 --- /dev/null +++ b/topologies/training-level1-me/files/.screenrc @@ -0,0 +1,19 @@ +# Turn off the startup message. +startup_message off +# Set the caption to the active windows. +caption always "%-Lw%{= BW}%50>%n%f* %t%{-}%+Lw%<" + +term screen-256color + +# New screens for various processes. +# Example: screen -t +# screen -t 7050SX-128 0 ssh aristaadmin@192.100.37.128 +screen -t CVP 1 ssh 192.168.0.5 +screen -t Spine1 2 ssh 192.168.0.11 +screen -t Spine2 3 ssh 192.168.0.12 +screen -t Leaf1 4 ssh 192.168.0.21 +screen -t Leaf2 5 ssh 192.168.0.22 +screen -t Leaf3 6 ssh 192.168.0.23 +screen -t Leaf4 7 ssh 192.168.0.24 +screen -t Host1 8 ssh 192.168.0.51 +screen -t Host2 9 ssh 192.168.0.52 diff --git a/topologies/training-level1-me/files/MenuOptions.yaml b/topologies/training-level1-me/files/MenuOptions.yaml new file mode 100644 index 000000000..8c0bf20bb --- /dev/null +++ b/topologies/training-level1-me/files/MenuOptions.yaml @@ -0,0 +1,255 @@ +--- +options: + reset: + - command: "/usr/local/bin/ConfigureTopology.py && bash /home/arista/Broadcaster/pushHostDefaultConfig.sh" + description: "Reset All Devices to Base ATD (reset)" + mlag: + - command: "/usr/local/bin/ConfigureTopology.py -t mlag" + description: "MLAG Lab (mlag)" + bgp: + - command: "/usr/local/bin/ConfigureTopology.py -t bgp" + description: "BGP Lab (bgp)" + vxlan: + - command: "/usr/local/bin/ConfigureTopology.py -t vxlan" + description: "VXLAN Lab (vxlan) excludes leaf3 instead of leaf4" + l2evpn: + - command: "/usr/local/bin/ConfigureTopology.py -t l2evpn" + description: "EVPN Type 2 Lab (l2evpn) excludes leaf3 instead of leaf4" + l3evpn: + - command: "/usr/local/bin/ConfigureTopology.py -t l3evpn" + description: "EVPN Type 5 Lab (l3evpn) excludes leaf3 instead of leaf4" + cvp: + - command: "/usr/local/bin/ConfigureTopology.py -t cvp" + description: "CVP lab (cvp)" + media: + - command: "bash /home/arista/Broadcaster/pushHostMediaConfig.sh && login.py" + description: "Broadcast Engineer Training (media)" +labconfiglets: + mlag: + spine1: + - "Spine1-MLAG-Lab" + - "VLANs" + spine2: + - "Spine2-MLAG-Lab" + - "VLANs" + leaf1: + - "Leaf1-MLAG-Lab" + - "VLANs" + leaf2: + - "Leaf2-MLAG-Lab" + - "VLANs" + leaf3: + - "Leaf3-MLAG-Lab" + - "VLANs" + leaf4: + - "VLANs" + cvx01: + - "cvx01-Controller" + host1: + - "Host1-ATD" + host2: + - "Host2-ATD" + bgp: + spine1: + - "Spine1-BGP-Lab" + spine2: + - "Spine2-BGP-Lab" + leaf1: + - "Leaf1-BGP-Lab" + leaf2: + - "Leaf2-BGP-Lab" + leaf3: + - "Leaf3-BGP-Lab" + leaf4: + - "Leaf4-BGP-Lab" + cvx01: + - "cvx01-Controller" + host1: + - "Host1-ATD" + host2: + - "Host2-ATD" + vxlan: + spine1: + - "Spine1-BGP-Lab" + spine2: + - "Spine2-BGP-Lab" + leaf1: + - "Leaf1-VXLAN-Lab" + - "VLANs" + leaf2: + - "Leaf2-VXLAN-Lab" + - "VLANs" + leaf3: + - "Leaf3-VXLAN-Lab" + - "VLANs" + leaf4: + - "Leaf4-VXLAN-Lab" + - "VLANs" + cvx01: + - "cvx01-Controller" + host1: + - "Host1-ATD" + host2: + - "Host2-ATD" + l2evpn: + spine1: + - "Spine1-L2EVPN-Lab" + spine2: + - "Spine2-L2EVPN-Lab" + leaf1: + - "Leaf1-L2EVPN-Lab" + - "VLANs" + leaf2: + - "Leaf2-L2EVPN-Lab" + - "VLANs" + leaf3: + - "VLANs" + leaf4: + - "Leaf4-L2EVPN-Lab" + - "VLANs" + cvx01: + - "cvx01-Controller" + host1: + - "Host1-ATD" + host2: + - "Host2-ATD" + l3evpn: + spine1: + - "Spine1-L3EVPN-Lab" + spine2: + - "Spine2-L3EVPN-Lab" + leaf1: + - "Leaf1-L3EVPN-Lab" + leaf2: + - "Leaf2-L3EVPN-Lab" + leaf3: + - "VLANs" + leaf4: + - "Leaf4-L3EVPN-Lab" + cvx01: + - "cvx01-Controller" + host1: + - "Host1-ATD" + host2: + - "Host2-ATD" + cvp: + spine1: + - "Spine1-BGP-Lab" + spine2: + - "Spine2-BGP-Lab" + leaf1: + - "Leaf1-BGP-Lab" + leaf2: + - "Leaf2-BGP-Lab" + leaf3: + - "Leaf3-BGP-Lab" + leaf4: + - "Leaf4-BGP-Lab-Full" + cvx01: + - "cvx01-Controller" + host1: + - "Host1-ATD" + host2: + - "Host2-ATD" + media-reset: + spine1: + - "media-spine1-IP-Intro-start" + spine2: + - "media-spine2-IP-Intro-start" + leaf1: + - "media-leaf1-IP-Intro-start" + leaf2: + - "media-leaf2-IP-Intro-start" + leaf3: + - "media-leaf3-IP-Intro-start" + leaf4: + - "media-leaf4-IP-Intro-start" + host1: + - "Host1-Media" + host2: + - "Host2-Media" + media-intro: + spine1: + - "media-spine1-IP-Intro-start" + spine2: + - "media-spine2-IP-Intro-start" + leaf1: + - "media-leaf1-IP-Intro-start" + leaf2: + - "media-leaf2-IP-Intro-start" + leaf3: + - "media-leaf3-IP-Intro-start" + leaf4: + - "media-leaf4-IP-Intro-start" + host1: + - "Host1-Media" + host2: + - "Host2-Media" + media-vlan: + spine1: + - "media-spine1-VLAN-STP-start" + spine2: + - "media-spine2-VLAN-STP-start" + leaf1: + - "media-leaf1-VLAN-STP-start" + leaf2: + - "media-leaf2-VLAN-STP-start" + leaf3: + - "media-leaf3-VLAN-STP-start" + leaf4: + - "media-leaf4-VLAN-STP-start" + host1: + - "Host1-Media" + host2: + - "Host2-Media" + media-ospf: + spine1: + - "media-spine1-OSPF-start" + spine2: + - "media-spine2-OSPF-start" + leaf1: + - "media-leaf1-OSPF-start" + leaf2: + - "media-leaf2-OSPF-start" + leaf3: + - "media-leaf3-OSPF-start" + leaf4: + - "media-leaf4-OSPF-start" + host1: + - "Host1-Media" + host2: + - "Host2-Media" + media-bgp: + spine1: + - "media-spine1-BGP-start" + spine2: + - "media-spine2-BGP-start" + leaf1: + - "media-leaf1-BGP-start" + leaf2: + - "media-leaf2-BGP-start" + leaf3: + - "media-leaf3-BGP-start" + leaf4: + - "media-leaf4-BGP-start" + host1: + - "Host1-Media" + host2: + - "Host2-Media" + media-mcast: + spine1: + - "media-spine1-Multicast-lab" + spine2: + - "media-spine2-Multicast-lab" + leaf1: + - "media-leaf1-Multicast-lab" + leaf2: + - "media-leaf2-Multicast-lab" + leaf3: + - "media-leaf3-Multicast-lab" + leaf4: + - "media-leaf4-Multicast-lab" + host1: + - "Host1-Media" + host2: + - "Host2-Media" diff --git a/topologies/training-level1-me/files/apps/coder/coder.yaml b/topologies/training-level1-me/files/apps/coder/coder.yaml new file mode 100644 index 000000000..80cc852d1 --- /dev/null +++ b/topologies/training-level1-me/files/apps/coder/coder.yaml @@ -0,0 +1,4 @@ +bind-addr: 127.0.0.1:8080 +auth: password +password: {ARISTA_REPLACE} +cert: false \ No newline at end of file diff --git a/topologies/training-level1-me/files/apps/coder/labfiles/.placeholder b/topologies/training-level1-me/files/apps/coder/labfiles/.placeholder new file mode 100644 index 000000000..e69de29bb diff --git a/topologies/training-level1-me/files/apps/ssh/web.json b/topologies/training-level1-me/files/apps/ssh/web.json new file mode 100644 index 000000000..13fac47dd --- /dev/null +++ b/topologies/training-level1-me/files/apps/ssh/web.json @@ -0,0 +1,76 @@ +{ + "listen": { + "ip": "0.0.0.0", + "port": 2222 + }, + "user": { + "name": null, + "password": null, + "privatekey": null + }, + "ssh": { + "host": null, + "port": 22, + "localAddress": null, + "localPort": null, + "term": "xterm-color", + "readyTimeout": 20000, + "keepaliveInterval": 120000, + "keepaliveCountMax": 10, + "allowedSubnets": [ "192.168.0.0/16", "10.0.0.0/8", "172.16.0.0/12" ] + }, + "terminal": { + "cursorBlink": true, + "scrollback": 10000, + "tabStopWidth": 8, + "bellStyle": "sound" + }, + "header": { + "text": null, + "background": "green" + }, + "session": { + "name": "WebSSH2", + "secret": "mysecret" + }, + "options": { + "challengeButton": true, + "allowreauth": true + }, + "algorithms": { + "kex": [ + "ecdh-sha2-nistp256", + "ecdh-sha2-nistp384", + "ecdh-sha2-nistp521", + "diffie-hellman-group-exchange-sha256", + "diffie-hellman-group14-sha1" + ], + "cipher": [ + "aes128-ctr", + "aes192-ctr", + "aes256-ctr", + "aes128-gcm", + "aes128-gcm@openssh.com", + "aes256-gcm", + "aes256-gcm@openssh.com", + "aes256-cbc" + ], + "hmac": [ + "hmac-sha2-256", + "hmac-sha2-512", + "hmac-sha1" + ], + "compress": [ + "none", + "zlib@openssh.com", + "zlib" + ] + }, + "serverlog": { + "client": false, + "server": false + }, + "accesslog": false, + "verify": false, + "safeShutdownDuration": 300 + } \ No newline at end of file diff --git a/topologies/training-level1-me/files/apps/uilanding/modules.yaml b/topologies/training-level1-me/files/apps/uilanding/modules.yaml new file mode 100644 index 000000000..fb504a967 --- /dev/null +++ b/topologies/training-level1-me/files/apps/uilanding/modules.yaml @@ -0,0 +1,27 @@ +topology: + image: "atd-topo.png" + nodes: + Spine1: + coords: "208,22,392,106" + ip: "192.168.0.11" + Spine2: + coords: "505,21,687,106" + ip: "192.168.0.12" + Leaf1: + coords: "24,317,207,402" + ip: "192.168.0.21" + Leaf2: + coords: "248,317,431,403" + ip: "192.168.0.22" + Leaf3: + coords: "472,317,654,401" + ip: "192.168.0.23" + Leaf4: + coords: "697,317,879,401" + ip: "192.168.0.24" + Host1: + coords: "139,472,323,557" + ip: "192.168.0.51" + Host2: + coords: "588,473,772,557" + ip: "192.168.0.52" diff --git a/topologies/training-level1-me/files/apps/webui/.vncpass_clear b/topologies/training-level1-me/files/apps/webui/.vncpass_clear new file mode 100644 index 000000000..cd09dd7a5 --- /dev/null +++ b/topologies/training-level1-me/files/apps/webui/.vncpass_clear @@ -0,0 +1 @@ +@rista1 \ No newline at end of file diff --git a/topologies/training-level1-me/files/cvp/cvp_info.yaml b/topologies/training-level1-me/files/cvp/cvp_info.yaml new file mode 100644 index 000000000..eee027e4b --- /dev/null +++ b/topologies/training-level1-me/files/cvp/cvp_info.yaml @@ -0,0 +1,44 @@ +cvp_info: + containers: + Tenant: + nodes: + Leaf: + parent: Tenant + nodes: + - leaf1 + - leaf2 + - leaf3 + - leaf4 + Spine: + parent: Tenant + nodes: + - spine1 + - spine2 + Hosts: + parent: Tenant + nodes: + - host1 + - host2 + snapshots: + configlets: + containers: + Tenant: + - ATD-INFRA + netelements: + spine1: + - spine1-base + spine2: + - spine2-base + leaf1: + - leaf1-base + leaf2: + - leaf2-base + leaf3: + - leaf3-base + leaf4: + - leaf4-base + host1: + - host1-base + host2: + - host2-base + \ No newline at end of file diff --git a/topologies/training-level1-me/files/hosts b/topologies/training-level1-me/files/hosts new file mode 100644 index 000000000..a299812df --- /dev/null +++ b/topologies/training-level1-me/files/hosts @@ -0,0 +1,18 @@ +127.0.0.1 localhost +192.168.0.11 spine1 +192.168.0.12 spine2 +192.168.0.13 spine3 +192.168.0.14 spine4 +192.168.0.21 leaf1 +192.168.0.22 leaf2 +192.168.0.23 leaf3 +192.168.0.24 leaf4 +192.168.0.41 server1 +192.168.0.42 server2 +192.168.0.43 server3 +192.168.0.44 server4 +192.168.0.51 host1 +192.168.0.52 host2 +192.168.0.53 host3 +192.168.0.54 host4 +192.168.0.5 cvp diff --git a/topologies/training-level1-me/files/menus/default.yaml b/topologies/training-level1-me/files/menus/default.yaml new file mode 100644 index 000000000..695584577 --- /dev/null +++ b/topologies/training-level1-me/files/menus/default.yaml @@ -0,0 +1,2 @@ +--- +default_menu: training-l1.yaml \ No newline at end of file diff --git a/topologies/training-level1-me/files/menus/training-l1.yaml b/topologies/training-level1-me/files/menus/training-l1.yaml new file mode 100644 index 000000000..cd11197dc --- /dev/null +++ b/topologies/training-level1-me/files/menus/training-l1.yaml @@ -0,0 +1,22 @@ +--- + lab_list: + reset: + description: "Reset All Devices to Base Lab (reset)" + labconfiglets: + reset: + spine1: + - "spine1-base" + spine2: + - "spine2-base" + leaf1: + - "leaf1-base" + leaf2: + - "leaf2-base" + leaf3: + - "leaf3-base" + leaf4: + - "leaf4-base" + host1: + - "host1-base" + host2: + - "host2-base" \ No newline at end of file diff --git a/topologies/training-level1-me/files/scripts/Authenticate-CVP b/topologies/training-level1-me/files/scripts/Authenticate-CVP new file mode 100644 index 000000000..144bb13eb --- /dev/null +++ b/topologies/training-level1-me/files/scripts/Authenticate-CVP @@ -0,0 +1,32 @@ +import requests +import json + +# Set Script Variables + +CVP_HOST = "192.168.0.5" +CVP_USER = "arista" +CVP_PASS = "arista" + +# Fix for requests certification issue + +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + +# Create an HTTP session to the CVP server + +url = "https://%s"%CVP_HOST +headers = { 'Content-Type': 'application/json' } +loginURL = "/web/login/authenticate.do" +authenticateData = json.dumps({'userId' : CVP_USER, 'password' : CVP_PASS}) +response = requests.post(url+loginURL,data=authenticateData,headers=headers,verify=False) +assert response.ok +cookies = response.cookies +output = response.json() + +# Print user details + +print "User Name:%s\n "%output['username'] +print "First Name: %s\n "%output['user']['firstName'] +print "Last Name: %s\n "%output['user']['lastName'] +print "User Permissions: %s\n "%output['permissionList'] +print "Cookie Jar: %s\n "%cookies diff --git a/topologies/training-level1-me/files/scripts/Authenticate-CVP2 b/topologies/training-level1-me/files/scripts/Authenticate-CVP2 new file mode 100644 index 000000000..3f6bf9190 --- /dev/null +++ b/topologies/training-level1-me/files/scripts/Authenticate-CVP2 @@ -0,0 +1,48 @@ +import requests +import json + +# Set Script Variables + +CVP_HOST = "192.168.0.5" +CVP_USER = "arista" +CVP_PASS = "arista" + +# Fix for requests certification issue + +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + +# Create an HTTP session to the CVP server + +url = "https://%s"%CVP_HOST +headers = { 'Content-Type': 'application/json' } +loginURL = "/web/login/authenticate.do" +authenticateData = json.dumps({'userId' : CVP_USER, 'password' : CVP_PASS}) +response = requests.post(url+loginURL,data=authenticateData,headers=headers,verify=False) +assert response.ok +cookies = response.cookies +output = response.json() + +# Print user details + +print "User Name:%s\n "%output['username'] +print "First Name: %s\n "%output['user']['firstName'] +print "Last Name: %s\n "%output['user']['lastName'] +print "User Permissions: %s\n "%output['permissionList'] +print "Cookie Jar: %s\n "%cookies + +#Create an HTTP GET request to the CVP server + +getConfigletURL = "/cvpservice/configlet/getConfiglets.do?" +getConfigletParams = {'startIndex':'0','endIndex':'0','type':'Configlet'} +response = requests.get(url+getConfigletURL,cookies=cookies, params=getConfigletParams,verify=False) +assert response.ok +outputConfiglets = response.json() + +# Print Configlet details + +for configlet in outputConfiglets['data']: + print "ConfigletName: %s"%configlet['name'] + print "ConfigletKey: %s"%configlet['key'] + print "\n" + diff --git a/topologies/training-level1-me/files/scripts/Authenticate-CVP3 b/topologies/training-level1-me/files/scripts/Authenticate-CVP3 new file mode 100644 index 000000000..2445806ea --- /dev/null +++ b/topologies/training-level1-me/files/scripts/Authenticate-CVP3 @@ -0,0 +1,95 @@ +import requests +import json + +# Set Script Variables + +CVP_HOST = "192.168.0.5" +CVP_USER = "arista" +CVP_PASS = "arista" + +# Fix for requests certification issue + +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + +# Create an HTTP session to the CVP server + +url = "https://%s"%CVP_HOST +headers = { 'Content-Type': 'application/json' } +loginURL = "/web/login/authenticate.do" +authenticateData = json.dumps({'userId' : CVP_USER, 'password' : CVP_PASS}) +response = requests.post(url+loginURL,data=authenticateData,headers=headers,verify=False) +assert response.ok +cookies = response.cookies +output = response.json() + +# Print user details + +print "User Name:%s\n "%output['username'] +print "First Name: %s\n "%output['user']['firstName'] +print "Last Name: %s\n "%output['user']['lastName'] +print "User Permissions: %s\n "%output['permissionList'] +print "Cookie Jar: %s\n "%cookies + +#Create an HTTP GET request to the CVP server + +getConfigletURL = "/cvpservice/configlet/getConfiglets.do?" +getConfigletParams = {'startIndex':'0','endIndex':'0','type':'Configlet'} +response = requests.get(url+getConfigletURL,cookies=cookies, params=getConfigletParams,verify=False) +assert response.ok +outputConfiglets = response.json() + +# Print Configlet details + +for configlet in outputConfiglets['data']: + print "ConfigletName: %s"%configlet['name'] + print "ConfigletKey: %s"%configlet['key'] + print "\n" +# Create an HTTP GET request to the CVP server + +getConfigletHistoryURL = "/cvpservice/configlet/getConfigletHistory.do?" +getConfigletParams = {'configletId':'configlet_32_438214998013','startIndex':'0','endIndex':'0'} +response = requests.get(url+getConfigletHistoryURL,cookies=cookies, params=getConfigletParams,verify=False) +assert response.ok +outputConfigletHistory = response.json() + +# Print Configlet details + +for entry in outputConfigletHistory['configletHistory']: + print "ConfigletKey: %s"%entry['key'] + print "ConfigletOldConfig: %s"%entry['oldConfig'] + print "ConfigletNewConfig: %s"%entry['newConfig'] + print "\n" + + +# Create an HTTP GET request to the CVP server + +getConfigletDetailURL = "/cvpservice/configlet/getConfigletByName.do?" +getConfigletParams = {'name':'VLANs'} +response = requests.get(url+getConfigletDetailURL,cookies=cookies, params=getConfigletParams,verify=False) +assert response.ok +outputConfigletDetail = response.json() + +# Print Configlet details + +print "ConfigletKey: %s"%outputConfigletDetail['key'] +print "ConfigletName: %s"%outputConfigletDetail['name'] +print "ConfigletConfig: %s"%outputConfigletDetail['config'] +print "ConfigletNote: %s"%outputConfigletDetail['note'] +print "\n" + + +# Create an HTTP POST request to the CVP server + +headers = { 'Content-Type': 'application/json' } +postConfigletChangeURL = "/cvpservice/configlet/updateConfiglet.do" +changeData = json.dumps({"config": "! some configuration here", "key": "configlet_32_438214998013", "name": "VLANs"}) +response = requests.post(url+postConfigletChangeURL, cookies=cookies, data=changeData,headers=headers,verify=False) +assert response.ok +outputConfigletChange = response.json() + +# Print Configlet details + +print "ConfigletChange: %s"%outputConfigletChange['data'] +print "\n" + diff --git a/topologies/training-level1-me/files/scripts/Configlet1 b/topologies/training-level1-me/files/scripts/Configlet1 new file mode 100644 index 000000000..3f6bf9190 --- /dev/null +++ b/topologies/training-level1-me/files/scripts/Configlet1 @@ -0,0 +1,48 @@ +import requests +import json + +# Set Script Variables + +CVP_HOST = "192.168.0.5" +CVP_USER = "arista" +CVP_PASS = "arista" + +# Fix for requests certification issue + +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + +# Create an HTTP session to the CVP server + +url = "https://%s"%CVP_HOST +headers = { 'Content-Type': 'application/json' } +loginURL = "/web/login/authenticate.do" +authenticateData = json.dumps({'userId' : CVP_USER, 'password' : CVP_PASS}) +response = requests.post(url+loginURL,data=authenticateData,headers=headers,verify=False) +assert response.ok +cookies = response.cookies +output = response.json() + +# Print user details + +print "User Name:%s\n "%output['username'] +print "First Name: %s\n "%output['user']['firstName'] +print "Last Name: %s\n "%output['user']['lastName'] +print "User Permissions: %s\n "%output['permissionList'] +print "Cookie Jar: %s\n "%cookies + +#Create an HTTP GET request to the CVP server + +getConfigletURL = "/cvpservice/configlet/getConfiglets.do?" +getConfigletParams = {'startIndex':'0','endIndex':'0','type':'Configlet'} +response = requests.get(url+getConfigletURL,cookies=cookies, params=getConfigletParams,verify=False) +assert response.ok +outputConfiglets = response.json() + +# Print Configlet details + +for configlet in outputConfiglets['data']: + print "ConfigletName: %s"%configlet['name'] + print "ConfigletKey: %s"%configlet['key'] + print "\n" + diff --git a/topologies/training-level1-me/files/scripts/ConfigletChange b/topologies/training-level1-me/files/scripts/ConfigletChange new file mode 100644 index 000000000..691ff5864 --- /dev/null +++ b/topologies/training-level1-me/files/scripts/ConfigletChange @@ -0,0 +1,40 @@ +import requests +import json + +# Set Script Variables + +CVP_HOST = "192.168.0.5" +CVP_USER = "arista" +CVP_PASS = "arista" + +# Fix for requests certification issue + +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + +# Create an HTTP session to the CVP server + +url = "https://%s"%CVP_HOST +headers = { 'Content-Type': 'application/json' } +loginURL = "/web/login/authenticate.do" +authenticateData = json.dumps({'userId' : CVP_USER, 'password' : CVP_PASS}) +response = requests.post(url+loginURL,data=authenticateData,headers=headers,verify=False) +assert response.ok +cookies = response.cookies +output = response.json() + + +# Create an HTTP POST request to the CVP server + +headers = { 'Content-Type': 'application/json' } +postConfigletChangeURL = "/cvpservice/configlet/addNoteToConfiglet.do" +changeData = json.dumps({"note": "Configlet Changed by API", "key": "configlet_516_7018635812307"}) +response = requests.post(url+postConfigletChangeURL, cookies=cookies, data=changeData,headers=headers,verify=False) +assert response.ok +outputConfigletChange = response.json() + +# Print Configlet details + +print "ConfigletChange: %s"%outputConfigletChange['data'] +print "\n" + diff --git a/topologies/training-level1-me/files/scripts/ConfigletDetail b/topologies/training-level1-me/files/scripts/ConfigletDetail new file mode 100644 index 000000000..eb2a85937 --- /dev/null +++ b/topologies/training-level1-me/files/scripts/ConfigletDetail @@ -0,0 +1,43 @@ +import requests +import json + +# Set Script Variables + +CVP_HOST = "192.168.0.5" +CVP_USER = "arista" +CVP_PASS = "arista" + +# Fix for requests certification issue + +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + +# Create an HTTP session to the CVP server + +url = "https://%s"%CVP_HOST +headers = { 'Content-Type': 'application/json' } +loginURL = "/web/login/authenticate.do" +authenticateData = json.dumps({'userId' : CVP_USER, 'password' : CVP_PASS}) +response = requests.post(url+loginURL,data=authenticateData,headers=headers,verify=False) +assert response.ok +cookies = response.cookies +output = response.json() + +# Create an HTTP GET request to the CVP server + +getConfigletDetailURL = "/cvpservice/configlet/getConfigletByName.do?" +getConfigletParams = {'name':'VLANs'} +response = requests.get(url+getConfigletDetailURL,cookies=cookies, params=getConfigletParams,verify=False) +assert response.ok +outputConfigletDetail = response.json() + +# Print Configlet details + +print "ConfigletKey: %s"%outputConfigletDetail['key'] +print "ConfigletName: %s"%outputConfigletDetail['name'] +print "ConfigletConfig: %s"%outputConfigletDetail['config'] +print "ConfigletNote: %s"%outputConfigletDetail['note'] +print "\n" + + + diff --git a/topologies/training-level1-me/files/scripts/ConfigletHistory b/topologies/training-level1-me/files/scripts/ConfigletHistory new file mode 100644 index 000000000..71f1ac693 --- /dev/null +++ b/topologies/training-level1-me/files/scripts/ConfigletHistory @@ -0,0 +1,41 @@ +import requests +import json + +# Set Script Variables + +CVP_HOST = "192.168.0.5" +CVP_USER = "arista" +CVP_PASS = "arista" + +# Fix for requests certification issue + +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + +# Create an HTTP session to the CVP server + +url = "https://%s"%CVP_HOST +headers = { 'Content-Type': 'application/json' } +loginURL = "/web/login/authenticate.do" +authenticateData = json.dumps({'userId' : CVP_USER, 'password' : CVP_PASS}) +response = requests.post(url+loginURL,data=authenticateData,headers=headers,verify=False) +assert response.ok +cookies = response.cookies +output = response.json() + +# Create an HTTP GET request to the CVP server + +getConfigletHistoryURL = "/cvpservice/configlet/getConfigletHistory.do?" +getConfigletParams = {'configletId':'configlet_344_7351420097365','startIndex':'0','endIndex':'0'} +response = requests.get(url+getConfigletHistoryURL,cookies=cookies, params=getConfigletParams,verify=False) +assert response.ok +outputConfigletHistory = response.json() + +# Print Configlet details + +for entry in outputConfigletHistory['configletHistory']: + print "ConfigletKey: %s"%entry['key'] + print "ConfigletOldConfig: \n%s"%entry['oldConfig'] + print "ConfigletNewConfig: \n%s"%entry['newConfig'] + print "\n" + diff --git a/topologies/training-level1-me/files/scripts/TaskBase b/topologies/training-level1-me/files/scripts/TaskBase new file mode 100644 index 000000000..6f8deccaf --- /dev/null +++ b/topologies/training-level1-me/files/scripts/TaskBase @@ -0,0 +1,59 @@ +import requests +import json + +# Set Script Variables + +CVP_HOST = "192.168.0.5" +CVP_USER = "arista" +CVP_PASS = "arista" + +# Fix for requests certification issue + +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + +# Create an HTTP session to the CVP server + +url = "https://%s"%CVP_HOST +headers = { 'Content-Type': 'application/json' } +loginURL = "/web/login/authenticate.do" +authenticateData = json.dumps({'userId' : CVP_USER, 'password' : CVP_PASS}) +response = requests.post(url+loginURL,data=authenticateData,headers=headers,verify=False) +assert response.ok +cookies = response.cookies +output = response.json() + + +# Create an HTTP GET request to the CVP server + +getTasksURL = "/cvpservice/task/getTasks.do?" +getTasksParams = {'startIndex':'0','endIndex':'0','queryparam':'Pending'} +response = requests.get(url+getTasksURL,cookies=cookies, params=getTasksParams,verify=False) +assert response.ok +outputPendingTasks = response.json() + + +# Print Tasks Created by Current User +taskList = [ ] +for entry in outputPendingTasks['data']: + if str(entry['createdBy']) == str(CVP_USER): + print "TaskNumber: %s"%entry['workOrderId'] + taskList.append(str(entry['workOrderId'])) +print "TaskList: %s"%taskList + + + +# Create an HTTP POST request to the CVP server + +headers = { 'Content-Type': 'application/json' } +postTaskLogURL = "/cvpservice/workflow/addWorkOrderLog.do" +taskLogData = json.dumps({"taskId": taskList[1],"message": "This is a test Change","source": "CVP REST API"}) +response = requests.post(url+postTaskLogURL, cookies=cookies, data=taskLogData,headers=headers,verify=False) +assert response.ok +outputTaskLog = response.json() + +# Print Configlet details + +print "TaskLogAmmend: %s"%outputTaskLog['data'] +print "\n" + diff --git a/topologies/training-level1-me/files/scripts/TaskCVP1 b/topologies/training-level1-me/files/scripts/TaskCVP1 new file mode 100644 index 000000000..1ebd05764 --- /dev/null +++ b/topologies/training-level1-me/files/scripts/TaskCVP1 @@ -0,0 +1,48 @@ +import requests +import json + +# Set Script Variables + +CVP_HOST = "192.168.0.5" +CVP_USER = "arista" +CVP_PASS = "arista" + +# Fix for requests certification issue + +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + +# Create an HTTP session to the CVP server + +url = "https://%s"%CVP_HOST +headers = { 'Content-Type': 'application/json' } +loginURL = "/web/login/authenticate.do" +authenticateData = json.dumps({'userId' : CVP_USER, 'password' : CVP_PASS}) +response = requests.post(url+loginURL,data=authenticateData,headers=headers,verify=False) +assert response.ok +cookies = response.cookies +output = response.json() + +# Print user details + +print "User Name:%s\n "%output['username'] +print "First Name: %s\n "%output['user']['firstName'] +print "Last Name: %s\n "%output['user']['lastName'] + + +getTasksURL = "/cvpservice/task/getTasks.do?" +getTasksParams = {'startIndex':'0','endIndex':'0'} +response = requests.get(url+getTasksURL,cookies=cookies, params=getTasksParams,verify=False) +assert response.ok +outputPendingTasks = response.json() + + +# Print Tasks Created by Current User +taskList = [ ] +for entry in outputPendingTasks['data']: + if str(entry['createdBy']) == str(CVP_USER): + print( "TaskNumber: %s Description: %s" %(entry['workOrderId'],entry['description'])) + taskList.append(str(entry['workOrderId'])) +#print "TaskList: %s"%taskList + + diff --git a/topologies/training-level1-me/files/scripts/TaskExecute b/topologies/training-level1-me/files/scripts/TaskExecute new file mode 100644 index 000000000..3db487284 --- /dev/null +++ b/topologies/training-level1-me/files/scripts/TaskExecute @@ -0,0 +1,56 @@ +import requests +import json + +# Set Script Variables + +CVP_HOST = "192.168.0.5" +CVP_USER = "arista" +CVP_PASS = "arista" + +# Fix for requests certification issue + +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + +# Create an HTTP session to the CVP server + +url = "https://%s"%CVP_HOST +headers = { 'Content-Type': 'application/json' } +loginURL = "/web/login/authenticate.do" +authenticateData = json.dumps({'userId' : CVP_USER, 'password' : CVP_PASS}) +response = requests.post(url+loginURL,data=authenticateData,headers=headers,verify=False) +assert response.ok +cookies = response.cookies +output = response.json() + + +# Create an HTTP GET request to the CVP server + +getTasksURL = "/cvpservice/task/getTasks.do?" +getTasksParams = {'startIndex':'0','endIndex':'0','queryparam':'Pending'} +response = requests.get(url+getTasksURL,cookies=cookies, params=getTasksParams,verify=False) +assert response.ok +outputPendingTasks = response.json() + + +# Print Tasks Created by Current User +taskList = [ ] +for entry in outputPendingTasks['data']: + if str(entry['createdBy']) == str(CVP_USER): + print "TaskNumber: %s"%entry['workOrderId'] + taskList.append(str(entry['workOrderId'])) +print "TaskList: %s"%taskList + + + +headers = { 'Content-Type': 'application/json' } +postTaskExecuteURL = "/cvpservice/task/executeTask.do" +for taskNumber in taskList: + executeData = json.dumps({'data': [taskNumber]}) + response = requests.post(url+postTaskExecuteURL, cookies=cookies,data=executeData,headers=headers,verify=False) + assert response.ok + outputExecuteTask = response.json() + print (outputExecuteTask['data']) + print "Task: "+str(taskNumber)+" Execute: "+str(outputExecuteTask['data']) + print "\n" + diff --git a/topologies/training-level1-me/files/scripts/TaskLog b/topologies/training-level1-me/files/scripts/TaskLog new file mode 100644 index 000000000..c835008b8 --- /dev/null +++ b/topologies/training-level1-me/files/scripts/TaskLog @@ -0,0 +1,59 @@ +import requests +import json + +# Set Script Variables + +CVP_HOST = "192.168.0.5" +CVP_USER = "arista" +CVP_PASS = "arista" + +# Fix for requests certification issue + +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + +# Create an HTTP session to the CVP server + +url = "https://%s"%CVP_HOST +headers = { 'Content-Type': 'application/json' } +loginURL = "/web/login/authenticate.do" +authenticateData = json.dumps({'userId' : CVP_USER, 'password' : CVP_PASS}) +response = requests.post(url+loginURL,data=authenticateData,headers=headers,verify=False) +assert response.ok +cookies = response.cookies +output = response.json() + + +# Create an HTTP GET request to the CVP server + +getTasksURL = "/cvpservice/task/getTasks.do?" +getTasksParams = {'startIndex':'0','endIndex':'0'} +response = requests.get(url+getTasksURL,cookies=cookies, params=getTasksParams,verify=False) +assert response.ok +outputTasks = response.json() + + +# Print Tasks Created by Current User +taskList = [ ] +for entry in outputTasks['data']: + if str(entry['createdBy']) == str(CVP_USER): + print "TaskNumber: %s"%entry['workOrderId'] + taskList.append(str(entry['workOrderId'])) +print "TaskList: %s"%taskList + + + +# Create an HTTP POST request to the CVP server + +headers = { 'Content-Type': 'application/json' } +postTaskLogURL = "/cvpservice/workflow/addWorkOrderLog.do" +taskLogData = json.dumps({"taskId": taskList[0],"message": "This is a test Change","source": "CVP REST API"}) +response = requests.post(url+postTaskLogURL, cookies=cookies, data=taskLogData,headers=headers,verify=False) +assert response.ok +outputTaskLog = response.json() + +# Print Configlet details + +print "TaskLogAmmend: %s"%outputTaskLog['data'] +print "\n" + diff --git a/topologies/training-level1-me/files/scripts/TaskLog1 b/topologies/training-level1-me/files/scripts/TaskLog1 new file mode 100644 index 000000000..c835008b8 --- /dev/null +++ b/topologies/training-level1-me/files/scripts/TaskLog1 @@ -0,0 +1,59 @@ +import requests +import json + +# Set Script Variables + +CVP_HOST = "192.168.0.5" +CVP_USER = "arista" +CVP_PASS = "arista" + +# Fix for requests certification issue + +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + +# Create an HTTP session to the CVP server + +url = "https://%s"%CVP_HOST +headers = { 'Content-Type': 'application/json' } +loginURL = "/web/login/authenticate.do" +authenticateData = json.dumps({'userId' : CVP_USER, 'password' : CVP_PASS}) +response = requests.post(url+loginURL,data=authenticateData,headers=headers,verify=False) +assert response.ok +cookies = response.cookies +output = response.json() + + +# Create an HTTP GET request to the CVP server + +getTasksURL = "/cvpservice/task/getTasks.do?" +getTasksParams = {'startIndex':'0','endIndex':'0'} +response = requests.get(url+getTasksURL,cookies=cookies, params=getTasksParams,verify=False) +assert response.ok +outputTasks = response.json() + + +# Print Tasks Created by Current User +taskList = [ ] +for entry in outputTasks['data']: + if str(entry['createdBy']) == str(CVP_USER): + print "TaskNumber: %s"%entry['workOrderId'] + taskList.append(str(entry['workOrderId'])) +print "TaskList: %s"%taskList + + + +# Create an HTTP POST request to the CVP server + +headers = { 'Content-Type': 'application/json' } +postTaskLogURL = "/cvpservice/workflow/addWorkOrderLog.do" +taskLogData = json.dumps({"taskId": taskList[0],"message": "This is a test Change","source": "CVP REST API"}) +response = requests.post(url+postTaskLogURL, cookies=cookies, data=taskLogData,headers=headers,verify=False) +assert response.ok +outputTaskLog = response.json() + +# Print Configlet details + +print "TaskLogAmmend: %s"%outputTaskLog['data'] +print "\n" + diff --git a/topologies/training-level1-me/files/scripts/TaskLogView b/topologies/training-level1-me/files/scripts/TaskLogView new file mode 100644 index 000000000..7b34904dd --- /dev/null +++ b/topologies/training-level1-me/files/scripts/TaskLogView @@ -0,0 +1,51 @@ +import requests +import json +import pprint + +# Set Script Variables + +CVP_HOST = "192.168.0.5" +CVP_USER = "arista" +CVP_PASS = "arista" + +# Fix for requests certification issue + +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + +# Create an HTTP session to the CVP server + +url = "https://%s"%CVP_HOST +headers = { 'Content-Type': 'application/json' } +loginURL = "/web/login/authenticate.do" +authenticateData = json.dumps({'userId' : CVP_USER, 'password' : CVP_PASS}) +response = requests.post(url+loginURL,data=authenticateData,headers=headers,verify=False) +assert response.ok +cookies = response.cookies +output = response.json() + + +# Create an HTTP GET request to the CVP server + +getTasksURL = "/cvpservice/task/getTasks.do?" +getTasksParams = {'startIndex':'0','endIndex':'0'} +response = requests.get(url+getTasksURL,cookies=cookies, params=getTasksParams,verify=False) +assert response.ok +outputTasks = response.json() + +taskList = [ ] +for entry in outputTasks['data']: + if str(entry['createdBy']) == str(CVP_USER): + taskList.append(str(entry['workOrderId'])) + +getTaskLogURL = "/cvpservice/task/getLogsById.do?" +#getTaskLogParams = {'startIndex':'0','endIndex':'0','id':'0'} +getTaskLogParams = {'startIndex':'0','endIndex':'0','id':taskList[0]} +response = requests.get(url+getTaskLogURL,cookies=cookies, params=getTaskLogParams,verify=False) +assert response.ok +outputTaskLog = response.json() + +# Print TaskLog details +print "TaskLogOutput: %s" %outputTaskLog['data'] +print "\n" + diff --git a/topologies/training-level1-me/files/scripts/TaskNote b/topologies/training-level1-me/files/scripts/TaskNote new file mode 100644 index 000000000..6cd1d6cfd --- /dev/null +++ b/topologies/training-level1-me/files/scripts/TaskNote @@ -0,0 +1,52 @@ +import requests +import json +import pprint + +# Set Script Variables + +CVP_HOST = "192.168.0.5" +CVP_USER = "arista" +CVP_PASS = "arista" + +# Fix for requests certification issue + +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + +# Create an HTTP session to the CVP server + +url = "https://%s"%CVP_HOST +headers = { 'Content-Type': 'application/json' } +loginURL = "/web/login/authenticate.do" +authenticateData = json.dumps({'userId' : CVP_USER, 'password' : CVP_PASS}) +response = requests.post(url+loginURL,data=authenticateData,headers=headers,verify=False) +assert response.ok +cookies = response.cookies +output = response.json() + + +# Create an HTTP GET request to the CVP server + +getTasksURL = "/cvpservice/task/getTasks.do?" +getTasksParams = {'startIndex':'0','endIndex':'0'} +response = requests.get(url+getTasksURL,cookies=cookies, params=getTasksParams,verify=False) +assert response.ok +outputTasks = response.json() + +taskList = [ ] +for entry in outputTasks['data']: + if str(entry['createdBy']) == str(CVP_USER): + taskList.append(str(entry['workOrderId'])) + +headers = { 'Content-Type': 'application/json' } +postTaskNoteURL = "/cvpservice/task/addNoteToTask.do" +taskNoteData = json.dumps({"workOrderId": taskList[0],"note": "This is a test Change using the API"}) +response = requests.post(url+postTaskNoteURL, cookies=cookies, data=taskNoteData,headers=headers,verify=False) +assert response.ok +outputTaskNote = response.json() + +# Print Task details + +print "TaskNoteAmmend: %s"%outputTaskNote['data'] +print "\n" + diff --git a/topologies/training-level1-me/labguides/.gitignore b/topologies/training-level1-me/labguides/.gitignore new file mode 100644 index 000000000..ed86553f4 --- /dev/null +++ b/topologies/training-level1-me/labguides/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +build/ diff --git a/topologies/training-level1-me/labguides/Makefile b/topologies/training-level1-me/labguides/Makefile new file mode 100644 index 000000000..874ed2529 --- /dev/null +++ b/topologies/training-level1-me/labguides/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = python -msphinx +SPHINXPROJ = ATD +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/topologies/training-level1-me/labguides/readme.md b/topologies/training-level1-me/labguides/readme.md new file mode 100644 index 000000000..5a5369ecd --- /dev/null +++ b/topologies/training-level1-me/labguides/readme.md @@ -0,0 +1,12 @@ +# Lab Guides +In this folder are rST (restructured text) formatted lab guides for the ATD event. + +## Building +To build the documentation, you will need to install Sphinx and sphinx_bootstrap_theme with `pip`: + +`pip install sphinx sphinx_bootstrap_theme` + +## Contributing +At some point, this section may expand, but for now please make sure to review existing files for formatting guidelines. + +Please see https://github.com/ralsina/rst-cheatsheet/blob/master/rst-cheatsheet.rst for a cheat sheet. \ No newline at end of file diff --git a/topologies/training-level1-me/labguides/source/_static/arista_logo.png b/topologies/training-level1-me/labguides/source/_static/arista_logo.png new file mode 100644 index 000000000..2376e72b9 Binary files /dev/null and b/topologies/training-level1-me/labguides/source/_static/arista_logo.png differ diff --git a/topologies/training-level1-me/labguides/source/_static/arista_logo_160by26.png b/topologies/training-level1-me/labguides/source/_static/arista_logo_160by26.png new file mode 100644 index 000000000..d0d0cbeec Binary files /dev/null and b/topologies/training-level1-me/labguides/source/_static/arista_logo_160by26.png differ diff --git a/topologies/training-level1-me/labguides/source/_static/arista_logo_320by52.png b/topologies/training-level1-me/labguides/source/_static/arista_logo_320by52.png new file mode 100644 index 000000000..43dfa7ed2 Binary files /dev/null and b/topologies/training-level1-me/labguides/source/_static/arista_logo_320by52.png differ diff --git a/topologies/training-level1-me/labguides/source/_static/cloudvision-icon.png b/topologies/training-level1-me/labguides/source/_static/cloudvision-icon.png new file mode 100644 index 000000000..c309ed98e Binary files /dev/null and b/topologies/training-level1-me/labguides/source/_static/cloudvision-icon.png differ diff --git a/topologies/training-level1-me/labguides/source/_static/logo.jpg b/topologies/training-level1-me/labguides/source/_static/logo.jpg new file mode 100644 index 000000000..6eda41f7e Binary files /dev/null and b/topologies/training-level1-me/labguides/source/_static/logo.jpg differ diff --git a/topologies/training-level1-me/labguides/source/_static/my-styles.css b/topologies/training-level1-me/labguides/source/_static/my-styles.css new file mode 100644 index 000000000..1150528ee --- /dev/null +++ b/topologies/training-level1-me/labguides/source/_static/my-styles.css @@ -0,0 +1,41 @@ +body { + background-color: #FFFFFF; + color: #002859 +} + +.navbar-inverse { + background-image: -webkit-linear-gradient(#6d94bf, #446e9b 50%, #002859); + background-image: -o-linear-gradient(#6d94bf, #446e9b 50%, #002859); + background-image: -webkit-gradient(linear, left top, left bottom, from(#6d94bf), color-stop(50%, #446e9b), to(#002859)); + background-image: linear-gradient(#6d94bf, #446e9b 50%, #002859); + background-repeat: no-repeat; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff6d94bf', endColorstr='#ff002859', GradientType=0); + -webkit-filter: none; + filter: none; + border: 1px solid #345578; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3) +} + +.navbar-brand { + background: url("arista_logo_320by52.png") center / contain no-repeat; + display: inline-block; + width: 1px; + padding: 0 10px 0 60px; + margin-right: 30px; + margin-left: -30px; +} + +.navbar-brand>img { + display: inline-block; + padding: 0 100px 0 0px; + margin-right: 20px; +} +a.navbar-brand { + display: inline-block; + padding: 15px 0 0 120px; +} + +footer { + background-color: #002859; + color: #FFFFFF; +} diff --git a/topologies/training-level1-me/labguides/source/conf.py b/topologies/training-level1-me/labguides/source/conf.py new file mode 100644 index 000000000..afccec09c --- /dev/null +++ b/topologies/training-level1-me/labguides/source/conf.py @@ -0,0 +1,247 @@ +# -*- coding: utf-8 -*- +# +# ATD documentation build configuration file, created by +# sphinx-quickstart on Tue Apr 17 10:00:04 2018. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + +import sphinx_bootstrap_theme + +# Importing datetime module to auto update copyright year +from datetime import date + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +# Updating copyright var to auto update with current year +project = u'Arista ATD' +copyright = u'{0}, Arista Networks'.format(date.today().year) +author = u'Arista ATD atd-help@arista.com' + +# Show Source +html_show_sourcelink = False + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'Version 3.0' +# The full version, including alpha/beta/rc tags. +release = u'1' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +#html_theme = 'alabaster' +html_theme = 'bootstrap' +html_theme_path = sphinx_bootstrap_theme.get_html_theme_path() + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +html_theme_options = { + # Navigation bar title. (Default: ``project`` value) + 'navbar_title': "ATD", + + # Tab name for entire site. (Default: "Site") + 'navbar_site_name': "Table of Contents", + + # A list of tuples containing pages or urls to link to. + # Valid tuples should be in the following forms: + # (name, page) # a link to a page + # (name, "/aa/bb", 1) # a link to an arbitrary relative url + # (name, "http://example.com", True) # arbitrary absolute url + # Note the "1" or "True" value above as the third argument to indicate + # an arbitrary url. + 'navbar_links': [ + ("Arista", "http://www.arista.com", True), + ], + + # Render the next and previous page links in navbar. (Default: true) + 'navbar_sidebarrel': True, + + # Render the current pages TOC in the navbar. (Default: true) + 'navbar_pagenav': False, + + # Tab name for the current pages TOC. (Default: "Page") + 'navbar_pagenav_name': "Page", + + # Global TOC depth for "site" navbar tab. (Default: 1) + # Switching to -1 shows all levels. + 'globaltoc_depth': 2, + + # Include hidden TOCs in Site navbar? + # + # Note: If this is "false", you cannot have mixed ``:hidden:`` and + # non-hidden ``toctree`` directives in the same page, or else the build + # will break. + # + # Values: "true" (default) or "false" + 'globaltoc_includehidden': "true", + + # HTML navbar class (Default: "navbar") to attach to
element. + # For black navbar, do "navbar navbar-inverse" + #'navbar_class': "navbar navbar-inverse", + 'navbar_class': "navbar", + + # Fix navigation bar to top of page? + # Values: "true" (default) or "false" + 'navbar_fixed_top': "true", + + # Location of link to source. + # Options are "nav" (default), "footer" or anything else to exclude. + #'source_link_position': "nav", + + # Bootswatch (http://bootswatch.com/) theme. + # + # Options are nothing (default) or the name of a valid theme + # such as "cosmo" or "sandstone". + # + # The set of valid themes depend on the version of Bootstrap + # that's used (the next config option). + # + # Currently, the supported themes are: + # - Bootstrap 2: https://bootswatch.com/2 + # - Bootstrap 3: https://bootswatch.com/3 + 'bootswatch_theme': "spacelab", + + # Choose Bootstrap version. + # Values: "3" (default) or "2" (in quotes) + 'bootstrap_version': "3", +} + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = "AristaATD" + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = "Demo" + +# (Optional) Logo. Should be small enough to fit the navbar (ideally 24x24). +# Path should be relative to the ``_static`` files directory. +#html_logo = "cloudvision-icon.png" + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'AristaATD' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'ATD.tex', u'ATD Lab Guide', + u'ATD Help (atd-help@arista.com)', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'atd', u'ATD Lab Guide', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'ATD', u'ATD Lab Guide', + author, 'ATD', 'Lab Documentation.', + 'Miscellaneous'), +] + + +def setup(app): + app.add_stylesheet("my-styles.css") # also can be a full URL + # app.add_stylesheet("ANOTHER.css") + # app.add_stylesheet("AND_ANOTHER.css") diff --git a/topologies/training-level1-me/labguides/source/connecting.rst b/topologies/training-level1-me/labguides/source/connecting.rst new file mode 100644 index 000000000..10ae589ef --- /dev/null +++ b/topologies/training-level1-me/labguides/source/connecting.rst @@ -0,0 +1,28 @@ +Connecting +========== + +1. Log into the Arista Test Drive portal with your assigned URL. If you + don’t have one, please see your ATD staff. + +.. image:: images/connecting/nested_connecting_1.png + +2. SSH to the public address assigned to the LabAccess jumphost server (this is the Topology Address shown in the "Welcome to Arista's Test Drive!" picture above). The username is ``arista`` and the password is ``{REPLACE_PWD}``: + + .. code-block:: text + + ssh arista@{unique_address}.topo.testdrive.arista.com + +| + +.. image:: images/connecting/nested_connecting_2.png + :align: center + +| + +3. The LabAccess menu allows users to connect to each device and specify + lab topology. It is recommended to open multiple SSH sessions or use + the Screen option (under the SSH Menu) to jump between devices rapidly. + + You can also Access the LabAccess Menu from your browser by clicking on `Console Access` + +.. image:: images/connecting/nested_connecting_3.png diff --git a/topologies/training-level1-me/labguides/source/images/connecting/nested_connecting_1.png b/topologies/training-level1-me/labguides/source/images/connecting/nested_connecting_1.png new file mode 100644 index 000000000..aa76597b8 Binary files /dev/null and b/topologies/training-level1-me/labguides/source/images/connecting/nested_connecting_1.png differ diff --git a/topologies/training-level1-me/labguides/source/images/connecting/nested_connecting_2.png b/topologies/training-level1-me/labguides/source/images/connecting/nested_connecting_2.png new file mode 100644 index 000000000..2c6b51a2b Binary files /dev/null and b/topologies/training-level1-me/labguides/source/images/connecting/nested_connecting_2.png differ diff --git a/topologies/training-level1-me/labguides/source/images/connecting/nested_connecting_3.png b/topologies/training-level1-me/labguides/source/images/connecting/nested_connecting_3.png new file mode 100644 index 000000000..1cc7402a3 Binary files /dev/null and b/topologies/training-level1-me/labguides/source/images/connecting/nested_connecting_3.png differ diff --git a/topologies/training-level1-me/labguides/source/images/logo.jpg b/topologies/training-level1-me/labguides/source/images/logo.jpg new file mode 100644 index 000000000..6eda41f7e Binary files /dev/null and b/topologies/training-level1-me/labguides/source/images/logo.jpg differ diff --git a/topologies/training-level1-me/labguides/source/index.rst b/topologies/training-level1-me/labguides/source/index.rst new file mode 100644 index 000000000..bb76aaa2e --- /dev/null +++ b/topologies/training-level1-me/labguides/source/index.rst @@ -0,0 +1,8 @@ +Welcome to the Arista Training documentation! +======================================== + +.. toctree:: + :maxdepth: 1 + :caption: EOS Configuration + + connecting.rst diff --git a/topologies/training-level1-me/topo_build.yml b/topologies/training-level1-me/topo_build.yml new file mode 100644 index 000000000..969bd8f26 --- /dev/null +++ b/topologies/training-level1-me/topo_build.yml @@ -0,0 +1,241 @@ +host_cpu: 4 +cvp_cpu: 24 +cvp_nodes: 1 +veos_cpu: 2 +nodes: + - spine1: + ip_addr: 192.168.0.11 + sys_mac: 00:1c:73:b1:c6:01 + neighbors: + - neighborDevice: spine2 + neighborPort: Ethernet1 + port: Ethernet1 + - neighborDevice: leaf1 + neighborPort: Ethernet3 + port: Ethernet2 + - neighborDevice: leaf2 + neighborPort: Ethernet3 + port: Ethernet3 + - neighborDevice: leaf3 + neighborPort: Ethernet3 + port: Ethernet4 + - neighborDevice: leaf4 + neighborPort: Ethernet3 + port: Ethernet5 + - spine2: + ip_addr: 192.168.0.12 + sys_mac: 00:1c:73:b2:c6:01 + neighbors: + - neighborDevice: spine1 + neighborPort: Ethernet1 + port: Ethernet1 + - neighborDevice: leaf1 + neighborPort: Ethernet4 + port: Ethernet2 + - neighborDevice: leaf2 + neighborPort: Ethernet4 + port: Ethernet3 + - neighborDevice: leaf3 + neighborPort: Ethernet4 + port: Ethernet4 + - neighborDevice: leaf4 + neighborPort: Ethernet4 + port: Ethernet5 + - leaf1: + ip_addr: 192.168.0.21 + sys_mac: 00:1c:73:c1:c6:01 + neighbors: + - neighborDevice: leaf2 + neighborPort: Ethernet1 + port: Ethernet1 + - neighborDevice: leaf2 + neighborPort: Ethernet2 + port: Ethernet2 + - neighborDevice: spine1 + neighborPort: Ethernet2 + port: Ethernet3 + - neighborDevice: spine2 + neighborPort: Ethernet2 + port: Ethernet4 + - neighborDevice: host1 + neighborPort: Ethernet1 + port: Ethernet5 + - neighborDevice: host1 + neighborPort: Ethernet3 + port: Ethernet6 + # - neighborDevice: server1 + # neighborPort: Ethernet1 + # port: Ethernet11 + # - neighborDevice: server2 + # neighborPort: Ethernet2 + # port: Ethernet12 + - leaf2: + ip_addr: 192.168.0.22 + sys_mac: 00:1c:73:c2:c6:01 + neighbors: + - neighborDevice: leaf1 + neighborPort: Ethernet1 + port: Ethernet1 + - neighborDevice: leaf1 + neighborPort: Ethernet2 + port: Ethernet2 + - neighborDevice: spine1 + neighborPort: Ethernet3 + port: Ethernet3 + - neighborDevice: spine2 + neighborPort: Ethernet3 + port: Ethernet4 + - neighborDevice: host1 + neighborPort: Ethernet2 + port: Ethernet5 + - neighborDevice: host1 + neighborPort: Ethernet4 + port: Ethernet6 + # - neighborDevice: server1 + # neighborPort: Ethernet2 + # port: Ethernet11 + # - neighborDevice: server2 + # neighborPort: Ethernet1 + # port: Ethernet12 + - leaf3: + ip_addr: 192.168.0.23 + sys_mac: 00:1c:73:c3:c6:01 + neighbors: + - neighborDevice: leaf4 + neighborPort: Ethernet1 + port: Ethernet1 + - neighborDevice: leaf4 + neighborPort: Ethernet2 + port: Ethernet2 + - neighborDevice: spine1 + neighborPort: Ethernet4 + port: Ethernet3 + - neighborDevice: spine2 + neighborPort: Ethernet4 + port: Ethernet4 + - neighborDevice: host2 + neighborPort: Ethernet1 + port: Ethernet5 + - neighborDevice: host2 + neighborPort: Ethernet3 + port: Ethernet6 + # - neighborDevice: server3 + # neighborPort: Ethernet1 + # port: Ethernet11 + # - neighborDevice: server3 + # neighborPort: Ethernet2 + # port: Ethernet12 + - leaf4: + ip_addr: 192.168.0.24 + sys_mac: 00:1c:73:c4:c6:01 + neighbors: + - neighborDevice: leaf3 + neighborPort: Ethernet1 + port: Ethernet1 + - neighborDevice: leaf3 + neighborPort: Ethernet2 + port: Ethernet2 + - neighborDevice: spine1 + neighborPort: Ethernet5 + port: Ethernet3 + - neighborDevice: spine2 + neighborPort: Ethernet5 + port: Ethernet4 + - neighborDevice: host2 + neighborPort: Ethernet2 + port: Ethernet5 + - neighborDevice: host2 + neighborPort: Ethernet4 + port: Ethernet6 + # - neighborDevice: server4 + # neighborPort: Ethernet1 + # port: Ethernet11 + # - neighborDevice: server4 + # neighborPort: Ethernet2 + # port: Ethernet12 + - host1: + ip_addr: 192.168.0.51 + sys_mac: 00:1c:73:f1:c6:01 + neighbors: + - neighborDevice: leaf1 + neighborPort: Ethernet5 + port: Ethernet1 + - neighborDevice: leaf2 + neighborPort: Ethernet5 + port: Ethernet2 + - neighborDevice: leaf1 + neighborPort: Ethernet6 + port: Ethernet3 + - neighborDevice: leaf2 + neighborPort: Ethernet6 + port: Ethernet4 + - host2: + ip_addr: 192.168.0.52 + sys_mac: 00:1c:73:f2:c6:01 + neighbors: + - neighborDevice: leaf3 + neighborPort: Ethernet5 + port: Ethernet1 + - neighborDevice: leaf4 + neighborPort: Ethernet5 + port: Ethernet2 + - neighborDevice: leaf3 + neighborPort: Ethernet6 + port: Ethernet3 + - neighborDevice: leaf4 + neighborPort: Ethernet6 + port: Ethernet4 +servers: + - server1: + ami_name: "cloud-deploy-generic-CentOS-8-8.2.2004" + size: "t2.medium" + type: generic + ip_addr: 192.168.0.41 + sys_mac: 00:1c:73:e1:c6:01 + neighbors: + - neighborDevice: leaf1 + neighborPort: Ethernet11 + port: Ethernet1 + - neighborDevice: leaf2 + neighborPort: Ethernet11 + port: Ethernet2 + - server2: + ami_name: "cloud-deploy-generic-CentOS-8-8.2.2004" + size: "t2.medium" + type: generic + ip_addr: 192.168.0.42 + sys_mac: 00:1c:73:e2:c6:01 + neighbors: + - neighborDevice: leaf1 + neighborPort: Ethernet12 + port: Ethernet2 + - neighborDevice: leaf2 + neighborPort: Ethernet12 + port: Ethernet1 + - server3: + ami_name: "cloud-deploy-generic-CentOS-8-8.2.2004" + size: "t2.medium" + type: generic + ip_addr: 192.168.0.43 + sys_mac: 00:1c:73:e3:c6:01 + neighbors: + - neighborDevice: leaf3 + neighborPort: Ethernet11 + port: Ethernet1 + - neighborDevice: leaf3 + neighborPort: Ethernet12 + port: Ethernet2 + - server4: + ami_name: "cloud-deploy-generic-CentOS-8-8.2.2004" + size: "t2.medium" + type: generic + ip_addr: 192.168.0.44 + sys_mac: 00:1c:73:e4:c6:01 + neighbors: + - neighborDevice: leaf4 + neighborPort: Ethernet11 + port: Ethernet1 + - neighborDevice: leaf4 + neighborPort: Ethernet12 + port: Ethernet2 +additional_ssh_nodes: