diff --git a/.gitignore b/.gitignore index b1f3b64..467bae8 100644 --- a/.gitignore +++ b/.gitignore @@ -100,3 +100,5 @@ pip-selfcheck.json # Rope project settings .ropeproject +*.retry +*.swp diff --git a/core-deploy.retry b/core-deploy.retry deleted file mode 100644 index 11a615c..0000000 --- a/core-deploy.retry +++ /dev/null @@ -1,3 +0,0 @@ -ansible-vmx1 -ansible-vmx2 -ansible-vmx3 diff --git a/core/core-model.yml b/core/core-model.yml index 16de10f..5b8fec2 100644 --- a/core/core-model.yml +++ b/core/core-model.yml @@ -30,7 +30,7 @@ links: - {left: ansible-vmx2, left_port: ge-0/0/1, left_ip: 172.10.23.2, right: ansible-vmx3, right_port: ge-0/0/1, right_ip: 172.10.23.3, cost: 10 } - - {left: ansible-vmx1, left_port: ge-0/0/2, left_ip: 172.10.14.1, vlan: 40, + - {left: ansible-vmx1, left_port: ge-0/0/2, left_ip: 172.10.14.1, right: ansible-vmx4, right_port: ge-0/0/0, right_ip: 172.10.14.4, cost: 10 } bgp: diff --git a/core_config/ansible-vmx1-config.txt b/core_config/ansible-vmx1-config.txt index 4fff368..0c1f6ea 100644 --- a/core_config/ansible-vmx1-config.txt +++ b/core_config/ansible-vmx1-config.txt @@ -61,14 +61,10 @@ interfaces { ge-0/0/2 { description "ansible-vmx4" - vlan-tagging; - encapsulation flexible-ethernet-services; - unit 40 { - vlan-id 40; + unit 0 { family inet { address 172.10.14.1/24 } - family mpls; } } @@ -126,7 +122,7 @@ protocols { interface-type p2p; metric 10; } - interface ge-0/0/2.40 { + interface ge-0/0/2.0 { interface-type p2p; metric 10; } @@ -138,18 +134,18 @@ protocols { ldp { interface ge-0/0/0.0; interface ge-0/0/1.0; - interface ge-0/0/2.40; + interface ge-0/0/2.0; interface lo0.0; } rsvp { interface ge-0/0/0.0; interface ge-0/0/1.0; - interface ge-0/0/2.40; + interface ge-0/0/2.0; } mpls { interface ge-0/0/0.0; interface ge-0/0/1.0; - interface ge-0/0/2.40; + interface ge-0/0/2.0; } lldp { interface ge-0/0/0; diff --git a/core_config/ansible-vmx4-config.txt b/core_config/ansible-vmx4-config.txt new file mode 100644 index 0000000..65691cc --- /dev/null +++ b/core_config/ansible-vmx4-config.txt @@ -0,0 +1,133 @@ + +version 15.1F6.9 +system { + host-name ansible-vmx4; + no-redirects; + root-authentication { + encrypted-password "$5$mcE0Hfiq$JfBeC3QSAvnd1tjqlOhlYXDgVrwvd6S4G3oVj5wiMO7"; ## SECRET-DATA + } + login { + user salt { + uid 2001; + class super-user; + authentication { + encrypted-password "$5$yp7ziGTI$F5F.6AUlR8hDK2JIsw5WRrTLex/yTCWH3iSR1Auk293"; ## SECRET-DATA + ssh-rsa "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCjxY2hLZ+ju5wdK4GYNhKGgnS8EWLBoEVpo+xQkhDzkTiBx3HGAnmARcVV0B9MqrHZl1omdnirJeygWzVbVY4yPUqGgEcUsTTq9fvK4AjTwtaoB5txAosaOnZq0zewmuZ6EMi6E3RND6A3FGXkf1Il2jg3I8k/dGqdyFI80B7sWy90fk+EqsGMPxVc+l5vAtY2jm84ellxxzBsulxfCSKPH86hZ1GqZ8A1ZBWITu15NjQw0aGssSYGMMTa1T8eFyY4hHWqqdwgOlODg9mZwwP1JdJH79SRoTOjqGGixuAFDGAgH3fNX6u8wTmYya/z7WXH6B2XwiiaZYdcyEbMLPZt"; ## SECRET-DATA + } + } + } + services { + ssh; + netconf { + ssh; + traceoptions { + file nc.txt size 1m world-readable; + flag incoming; + } + } + } + syslog { + user * { + any emergency; + } + file messages { + any any; + authorization info; + } + file interactive-commands { + interactive-commands any; + } + } +} + +interfaces { + ge-0/0/0 { + description "ansible-vmx1" + unit 0 { + family inet { + address 172.10.14.4/24 + } + } + } + + fxp0 { + description "OOB to MGMT Network"; + unit 0 { + family inet { + address 10.39.0.44/20; + } + } + } + lo0 { + unit 0 { + family inet { + address 10.39.8.44/32; + } + } + } +} +routing-options { + router-id 10.39.8.44; + autonomous-system 65000; + static { + route 0.0.0.0/0 { + next-hop 10.39.0.1; + no-readvertise; + preference 255; + } + } +} +protocols { + bgp { + group Core { + type internal; + export __Ansible_Core_export; + local-address 10.39.8.44; + family inet { + unicast; + } + family inet-vpn { + unicast; + } + neighbor 10.39.8.41; + } + } + ospf { + area 0 { + interface ge-0/0/0.0 { + interface-type p2p; + metric 10; + } + interface lo0.0 { + passive; + } + } + } + ldp { + interface ge-0/0/0.0; + interface lo0.0; + } + rsvp { + interface ge-0/0/0.0; + } + mpls { + interface ge-0/0/0.0; + } + lldp { + interface ge-0/0/0; + } +} +policy-options { + policy-statement __Ansible_Core_export { + term ebgp { + from { + protocol bgp; + external; + } + then { + next-hop self; + accept; + } + } + } +} diff --git a/diff/ansible-vmx1-diff.txt b/diff/ansible-vmx1-diff.txt index e69de29..b3e493c 100644 --- a/diff/ansible-vmx1-diff.txt +++ b/diff/ansible-vmx1-diff.txt @@ -0,0 +1,23 @@ +[edit protocols rsvp] + interface ge-0/0/1.0 { ... } ++ interface ge-0/0/2.0; +- interface ge-0/0/2.40; +[edit protocols mpls] + interface ge-0/0/1.0 { ... } ++ interface ge-0/0/2.0; +- interface ge-0/0/2.40; +[edit protocols ospf area 0.0.0.0] + interface ge-0/0/1.0 { ... } ++ interface ge-0/0/2.0 { ++ interface-type p2p; ++ metric 10; ++ } + interface lo0.0 { ... } +[edit protocols ospf area 0.0.0.0] +- interface ge-0/0/2.40 { +- interface-type p2p; +- metric 10; +- } +[edit protocols ldp] ++ interface ge-0/0/2.0; +- interface ge-0/0/2.40; \ No newline at end of file diff --git a/diff/ansible-vmx4-diff.txt b/diff/ansible-vmx4-diff.txt new file mode 100644 index 0000000..8fdd771 --- /dev/null +++ b/diff/ansible-vmx4-diff.txt @@ -0,0 +1,20 @@ +[edit protocols rsvp] ++ interface ge-0/0/0.0; +- interface ge-0/0/0.40; +[edit protocols mpls] ++ interface ge-0/0/0.0; +- interface ge-0/0/0.40; +[edit protocols ospf area 0.0.0.0] ++ interface ge-0/0/0.0 { ++ interface-type p2p; ++ metric 10; ++ } + interface lo0.0 { ... } +[edit protocols ospf area 0.0.0.0] +- interface ge-0/0/0.40 { +- interface-type p2p; +- metric 10; +- } +[edit protocols ldp] ++ interface ge-0/0/0.0; +- interface ge-0/0/0.40; \ No newline at end of file diff --git a/nodes.yml b/nodes.yml index e3f6947..9725470 100644 --- a/nodes.yml +++ b/nodes.yml @@ -15,7 +15,7 @@ nodes: links: ge-0/0/0.0: { ip: 172.10.12.1, remote: ansible-vmx2 , cost: 10 , vlan: 0} ge-0/0/1.0: { ip: 172.10.13.1, remote: ansible-vmx3 , cost: 10 , vlan: 0} - ge-0/0/2.40: { ip: 172.10.14.1, remote: ansible-vmx4 , cost: 10 , vlan: 40} + ge-0/0/2.0: { ip: 172.10.14.1, remote: ansible-vmx4 , cost: 10 , vlan: 0} bgp: ibgp: rr: true @@ -68,7 +68,7 @@ nodes: mgmt: 10.39.0.44 rid: 10.39.8.44 links: - ge-0/0/0.40: { ip: 172.10.14.4, remote: ansible-vmx1 , cost: 10 , vlan: 40} + ge-0/0/0.0: { ip: 172.10.14.4, remote: ansible-vmx1 , cost: 10 , vlan: 0} bgp: ibgp: peers: diff --git a/validate.yml b/validate.yml new file mode 100644 index 0000000..eda474c --- /dev/null +++ b/validate.yml @@ -0,0 +1,77 @@ +--- +- name: Validate LLDP and Interfaces + gather_facts: no + hosts: all + tags: [ validate ] + tasks: + - name: Get BGP and LLDP output + napalm_get_facts: + hostname: "{{ ansible_host }}" + username: "{{ ansible_user }}" + dev_os: "{{ ansible_network_os }}" + optional_args: + key_file: "{{ ansible_ssh_private_key_file }}" + filter: + - lldp_neighbors + - bgp_neighbors + - interfaces_ip + - interfaces + - include_vars: "./nodes.yml" + - set_fact: node={{nodes[inventory_hostname]}} + - name: Validate core interfaces are up + assert: + that: napalm_interfaces[item.split('.')[0]].is_up == true + msg: | + Interface {{item}} on {{inventory_hostname}} is not operational + with_list: "{{node.links.keys()}}" + ignore_errors: true + - name: Validate LLDP neighbors + assert: + that: node.links[item.key].remote == napalm_lldp_neighbors[item.key.split('.')[0]][0].hostname + msg: | + Router {{inventory_hostname}} has incorrect neighbor on {{item.key}} interface + with_dict: "{{node.links}}" + ignore_errors: True + - name: Validate correct IP and subnet mask + assert: + that: + - napalm_interfaces_ip[item].ipv4.keys()[0] == node.links[item].ip + - napalm_interfaces_ip[item].ipv4.values()[0]['prefix_length'] == 24 + msg: | + Interface {{item}} on {{inventory_hostname}} has incorrect IP address + with_list: "{{node.links.keys()}}" + ignore_errors: True + - name: Validate BGP Sessions + assert: + that: + - napalm_bgp_neighbors.global.peers[item].is_up == true + msg: | + BGP neighbor {{item}} on {{inventory_hostname}} is not operational + with_list: "{{node.bgp.ibgp.peers}}" + ignore_errors: true + +- name: Ping test + gather_facts: no + hosts: all + tags: [ ping ] + tasks: + - include_vars: "./nodes.yml" + - set_fact: node={{nodes[inventory_hostname]}} + - name: Perform ping on JunOS nodes + napalm_ping: + hostname: "{{ ansible_host }}" + username: "{{ ansible_user }}" + dev_os: "{{ ansible_network_os }}" + optional_args: + key_file: "{{ ansible_ssh_private_key_file }}" + destination: "{{nodes[item].rid}}" + with_list: "{{nodes.keys()}}" + when: ansible_network_os == 'junos' + register: ping_result + - debug: var=ping_result + - name: Validate network reachability + assert: + that: item.results.success is defined + msg: "{{item.item}} is not reachable to {{inventory_hostname}}" + with_list: "{{hostvars[inventory_hostname].ping_result.results}}" + when: ansible_network_os == 'junos'