Skip to content
Snippets Groups Projects
Commit 4bf0352b authored by Simone Spinelli's avatar Simone Spinelli
Browse files

Ansible mechanics for migrating IPtrunk

parent 0fc352e3
No related branches found
No related tags found
1 merge request!9Migration of iptrunk
Showing
with 523 additions and 0 deletions
- name: Manage iptrunks migration
hosts: all
remote_user: admin
gather_facts: false
roles:
- Juniper.junos
- roles/iptrunk_migration
---
# tasks file for iptrunks
- name: Print the usage
ansible.builtin.debug:
msg:
- "Both 'verb' and 'config_object' are required."
- "Allowed verbs: 'deactivate', 'deploy', 'delete'. Use: -e 'verb=$verb'"
- "Allowed objects: 'all', 'trunk_interface', 'isis_interface'. Use: -e 'config_object=$config_object'"
when: ((verb is not defined) or (config_object is not defined)) or (verb not in verbs) or (config_object not in config_objects)
- name: Fail if arguments are not correct
ansible.builtin.meta: end_play
when: ((verb is not defined) or (config_object is not defined)) or (verb not in verbs) or (config_object not in config_objects)
- name: Import routers variables
ansible.builtin.include_vars:
dir: /opt/ansible_inventory/group_vars/routers
- name: Set an ID for this run
ansible.builtin.set_fact:
opid: "{{ lookup('community.general.random_string', length=18, special=false) }}"
config_is_different: "False"
- name: Load local info
ansible.builtin.set_fact:
local_side: "{{ wfo_trunk_json | community.general.json_query(query) }}"
vars:
query: "iptrunk.iptrunk_sides[?iptrunk_side_node.router_fqdn == '{{ inventory_hostname }}'] | [0]"
- name: Load netconf connection config
ansible.builtin.set_fact:
ansible_connection: "{{ netconf_access[local_side.iptrunk_side_node.router_vendor].ansible_connection }}"
ansible_network_os: "{{ netconf_access[local_side.iptrunk_side_node.router_vendor].ansible_network_os }}"
- name: Load remote info
ansible.builtin.set_fact:
remote_side: "{{ wfo_trunk_json | community.general.json_query(query) }}"
vars:
query: "iptrunk.iptrunk_sides[?iptrunk_side_node.router_fqdn != '{{ inventory_hostname }}'] | [0]"
- name: Set ansible_host to terminal server when router is offline
ansible.builtin.set_fact:
ansible_host: "{{ local_side.iptrunk_side_node.router_site.site_ts_address }}"
ansible_port: "{{ local_side.iptrunk_side_node.router_ts_port }}"
when:
( local_side.iptrunk_side_node.router_access_via_ts | ansible.builtin.bool ) is true
- name: Print the ID
ansible.builtin.debug:
msg: "{{ opid }}"
- name: Include compiling the template
ansible.builtin.include_tasks: iptrunks_compile_object.yaml
when: (verb in verbs)
- name: Include the deployment tasks if specified
ansible.builtin.include_tasks: iptrunks_deploy_object.yaml
when: verb == "deploy"
- name: Include the removal tasks if specified
ansible.builtin.include_tasks: iptrunks_remove_trunk.yaml
when: verb == "terminate"
- name: Include the modification tasks if specified
ansible.builtin.include_tasks: iptrunk_modify_trunk.yaml
when: verb == "modify"
Role Name
=========
A brief description of the role goes here.
Requirements
------------
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
Role Variables
--------------
A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
Dependencies
------------
A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
Example Playbook
----------------
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
- hosts: servers
roles:
- { role: username.rolename, x: 42 }
License
-------
BSD
Author Information
------------------
An optional section for the role authors to include contact information, or a website (HTML is not allowed).
galaxy_info:
author: your name
description: your role description
company: your company (optional)
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Choose a valid license ID from https://spdx.org - some suggested licenses:
# - BSD-3-Clause (default)
# - MIT
# - GPL-2.0-or-later
# - GPL-3.0-only
# - Apache-2.0
# - CC-BY-4.0
license: license (GPL-2.0-or-later, MIT, etc)
min_ansible_version: 2.1
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
# platforms:
# - name: Fedora
# versions:
# - all
# - 25
# - name: SomePlatform
# versions:
# - all
# - 1.0
# - 7
# - 99.99
galaxy_tags: []
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.
- name: Old side is sideA
ansible.builtin.set_fact:
new_ipv4_address: "{{side_a_ipv4_address}}"
new_ipv6_address: "{{side_a_ipv6_address}}"
when:
(replace_index|int) == 0
- name: Old side is sideB
ansible.builtin.set_fact:
new_ipv4_address: "{{side_b_ipv4_address}}"
new_ipv6_address: "{{side_b_ipv6_address}}"
when:
(replace_index|int) == 1
- name: Load local info
ansible.builtin.set_fact:
local_side: "{{ wfo_trunk_json | community.general.json_query(query) }}"
vars:
query: "iptrunk.iptrunk_sides[?iptrunk_side_node.router_fqdn == '{{ inventory_hostname }}'] | [0]"
- name: Load netconf connection config
ansible.builtin.set_fact:
ansible_connection: "{{ netconf_access[local_side.iptrunk_side_node.router_vendor].ansible_connection }}"
ansible_network_os: "{{ netconf_access[local_side.iptrunk_side_node.router_vendor].ansible_network_os }}"
---
- name: Set ansible_host to terminal server when router is offline
ansible.builtin.set_fact:
ansible_host: localhost
when:
local_side is defined and ( local_side.iptrunk_side_node.router_access_via_ts | ansible.builtin.bool ) is true and
(verb == "delete" or verb == "deactivate")
- name: Set ansible_host to terminal server when router is offline
ansible.builtin.set_fact:
ansible_host: localhost
when:
( new_node.router.router_access_via_ts | ansible.builtin.bool ) is true and
(verb == "deploy")
- name: Create a folder for all the templates
ansible.builtin.file:
path: "/var/tmp/ansible_run_{{ opid }}"
state: directory
mode: '0755'
delegate_to: localhost
- name: Print the template in "/var/tmp/ansible_run_{{ opid }}/{{ config_object }}.conf"
ansible.builtin.template:
src: "{{ new_node.router.router_vendor }}/{{ config_object }}.j2"
dest: "/var/tmp/ansible_run_{{ opid }}/{{ config_object }}.conf"
lstrip_blocks: true
trim_blocks: true
mode: '0755'
delegate_to: localhost
- name: Set netconf connection for trunk nodes
ansible.builtin.include_tasks: set_netconf_connection.yaml
when: verb == "delete" or verb == "deactivate"
- name: Set ansible_host to terminal server when router is offline
ansible.builtin.set_fact:
ansible_host: "{{ new_node.router.router_site.site_ts_address }}"
ansible_port: "{{ new_node.router.router_ts_port }}"
when:
( new_node.router.router_access_via_ts | ansible.builtin.bool ) is true and verb == "deploy"
---
- name: Deactivate Trunk interface on "{{ inventory_hostname }}" [CHECK ONLY][JUNIPER]
juniper_junos_config:
load: 'replace'
src: "/var/tmp/ansible_run_{{ opid }}/{{ config_object }}.conf"
format: set
config_mode: "private"
check: true
commit: false
register: response
when: >
verb == "deactivate" and
local_side.iptrunk_side_node.router_vendor == "juniper" and
dry_run | ansible.builtin.bool
- name: Show DRY diff of "{{ config_object }}"
ansible.builtin.debug:
msg: "{{ response }}"
when: >
verb == "deactivate"
and dry_run | ansible.builtin.bool and
local_side.iptrunk_side_node.router_vendor == "juniper"
- name: Deactivate Trunk interface on "{{ inventory_hostname }}" [AND COMMIT][JUNIPER]
juniper_junos_config:
load: 'replace'
src: "/var/tmp/ansible_run_{{ opid }}/{{ config_object }}.conf"
format: set
config_mode: "private"
commit: true
comment: "{{ commit_comment }}"
register: response
when: >
verb == "deactivate" and
local_side.iptrunk_side_node.router_vendor == "juniper" and
not (dry_run | ansible.builtin.bool)
- name: Show real diff of "{{ config_object }}"
ansible.builtin.debug:
msg: "{{ response }}"
when: >
verb == "deactivate" and
local_side.iptrunk_side_node.router_vendor == "juniper" and
not (dry_run | ansible.builtin.bool)
---
- name: Delete Trunk interface on "{{ inventory_hostname }}" [CHECK ONLY][JUNIPER]
juniper_junos_config:
load: 'replace'
src: "/var/tmp/ansible_run_{{ opid }}/{{ config_object }}.conf"
format: set
config_mode: "private"
check: true
commit: false
register: response
when: >
verb == "delete" and
local_side.iptrunk_side_node.router_vendor == "juniper" and
dry_run | ansible.builtin.bool
- name: Show DRY diff of "{{ config_object }}"
ansible.builtin.debug:
msg: "{{ response }}"
when: >
verb == "delete"
and dry_run | ansible.builtin.bool and
local_side.iptrunk_side_node.router_vendor == "juniper"
- name: Delete Trunk interface on "{{ inventory_hostname }}" [AND COMMIT][JUNIPER]
juniper_junos_config:
load: 'replace'
src: "/var/tmp/ansible_run_{{ opid }}/{{ config_object }}.conf"
format: set
config_mode: "private"
commit: true
comment: "{{ commit_comment }}"
register: response
when: >
verb == "delete" and
local_side.iptrunk_side_node.router_vendor == "juniper" and
not (dry_run | ansible.builtin.bool)
- name: Show real diff of "{{ config_object }}"
ansible.builtin.debug:
msg: "{{ response }}"
when: >
verb == "delete" and
local_side.iptrunk_side_node.router_vendor == "juniper" and
not (dry_run | ansible.builtin.bool)
- name: Print the ID
ansible.builtin.debug:
msg: "{{ new_side }}"
---
# tasks file for iptrunks
- name: Print the usage
ansible.builtin.debug:
msg:
- "Both 'verb' and 'config_object' are required."
- "Allowed verbs: 'deactivate', 'deploy', 'delete'. Use: -e 'verb=$verb'"
- "Allowed objects: 'all', 'trunk_interface', 'isis_interface'. Use: -e 'config_object=$config_object'"
when: ((verb is not defined) or (config_object is not defined)) or (verb not in verbs) or (config_object not in config_objects)
- name: Fail if arguments are not correct
ansible.builtin.meta: end_play
when: ((verb is not defined) or (config_object is not defined)) or (verb not in verbs) or (config_object not in config_objects)
- name: Import routers variables
ansible.builtin.include_vars:
dir: /opt/ansible_inventory/group_vars/routers
- name: Set an ID for this run
ansible.builtin.set_fact:
opid: "{{ lookup('community.general.random_string', length=18, special=false) }}"
config_is_different: "False"
- name: Lets take a look at trunk
ansible.builtin.debug:
msg: "{{ wfo_trunk }}"
#- name: Lets take a look at trunk
# ansible.builtin.debug:
# msg: "{{ trunks[0] }}"
- name: The old node is
ansible.builtin.debug:
msg: "{{ old_node }}"
- name: The new node is
ansible.builtin.debug:
msg: "{{ new_node.router.router_fqdn }}"
- name: Select the correct IPaddresses
ansible.builtin.include_tasks: calculate_ips.yaml
when: verb == "deploy"
- name: Calculate local side
ansible.builtin.include_tasks: calculate_local_side.yaml
when: verb == "delete" or verb == "deactivate"
- name: Set netconf connection for trunk nodes
ansible.builtin.include_tasks: set_netconf_connection.yaml
when: verb == "delete" or verb == "deactivate"
- name: Set netconf connection for new side
ansible.builtin.set_fact:
ansible_host: "{{ new_node.router.router_site.site_ts_address }}"
ansible_port: "{{ new_node.router.router_ts_port }}"
when:
( new_node.router.router_access_via_ts | ansible.builtin.bool ) is true
when: verb == "deploy"
- name: Print the ID
ansible.builtin.debug:
msg: "{{ opid }}"
- name: Include compiling the template
ansible.builtin.include_tasks: iptrunk_compile_template.yaml
when: (verb in verbs)
- name: Include the modification tasks if specified
ansible.builtin.include_tasks: iptrunk_deactivate_trunk_side.yaml
when: verb == "deactivate" and inventory_hostname == old_node
- name: Include the removal tasks if specified
ansible.builtin.include_tasks: iptrunk_delete_trunk_side.yaml
when: verb == "delete" and inventory_hostname == old_node
- name: Include the deployment tasks if specified
ansible.builtin.include_tasks: iptrunk_deploy_object.yaml
when: verb == "deploy" and inventory_hostname == new_node.router.router_fqdn
- name: Set ansible_host to terminal server when router is offline
ansible.builtin.set_fact:
ansible_host: "{{ local_side.iptrunk_side_node.router_site.site_ts_address }}"
ansible_port: "{{ local_side.iptrunk_side_node.router_ts_port }}"
when:
( local_side.iptrunk_side_node.router_access_via_ts | ansible.builtin.bool ) is true
deactivate protocols isis interface {{ local_side.iptrunk_side_ae_iface }}.0
deactivate interfaces {{ local_side.iptrunk_side_ae_iface }}
{% for iface in local_side.iptrunk_side_ae_members %}
deactivate interfaces {{ iface }}
deactivate protocols lldp interface {{ iface }}
{% endfor %}
delete protocols isis interface {{ local_side.iptrunk_side_ae_iface }}
delete interfaces {{ local_side.iptrunk_side_ae_iface }}
{% for iface in local_side.iptrunk_side_ae_members %}
delete interfaces {{ iface }}
delete protocols lldp interface {{ iface }}
{% endfor %}
protocols {
isis {
replace: interface {{ new_side.ae_name }}.0 {
point-to-point;
level 2 {
post-convergence-lfa {
node-protection;
}
metric {{ new_side.isis_metric }};
}
}
}
}
{##}
{# I need to sort the source and the destination alfabetically #}
{% set trunk_direction_name = [ wfo_trunk.iptrunk.iptrunk_sides[0].iptrunk_side_node.router_fqdn.split(".")[1], wfo_trunk.iptrunk.iptrunk_sides[1].iptrunk_side_node.router_fqdn.split(".")[1] ] %}
{% set trunk_direction_name_sorted = trunk_direction_name|sort %}
{##}
{% if new_side is defined %}
interfaces {
replace: {{new_side.ae_name}} {
description "LAG INFRASTRUCTURE BACKBONE ${{ new_side.port_sid }} | {{ trunk_direction_name_sorted[0] }}-{{ trunk_direction_name_sorted[1] }}";
mtu 9192;
aggregated-ether-options {
minimum-links {{new_side.minimum_links}};
{#link-speed {{common.link_speed}};#}
lacp {
active;
periodic fast;
}
}
unit 0 {
description "SRV_GLOBAL INFRASTRUCTURE BACKBONE #{{ trunk_direction_name_sorted[0] }}-{{ trunk_direction_name_sorted[1] }}-IPTRUNK ${{ new_side.id }}| {{ trunk_direction_name_sorted[0] }}-{{ trunk_direction_name_sorted[1] }}";
family inet {
accounting {
source-class-usage {
input;
}
}
mtu 9000;
filter {
input bone-in;
output bone-out;
}
address {{new_ipv4_address}};
}
family iso;
family inet6 {
mtu 9000;
filter {
input bone6-in;
output bone6-out;
}
address {{new_ipv6_address}};
}
family mpls {
maximum-labels 5;
}
}
}
{% for member in new_side.members %}
replace: {{member}} {
description "PHY INFRASTRUCTURE BACKBONE P_{{new_side.ae_name}} | {{ trunk_direction_name_sorted[0] }}-{{ trunk_direction_name_sorted[1] }}";
gigether-options {
802.3ad {{new_side.ae_name}};
}
}
{% endfor %}
}
{% endif %}
---
# vars file for iptrunk_migration
dry_run: "True"
verbs:
- "deactivate"
- "deploy"
- "delete"
config_objects:
- "deactivate"
- "delete"
- "trunk_interface"
- "isis_interface"
- "trunk_deprovision"
wfo_trunk: "{{ wfo_trunk_json }}"
config_object: "{{ object }}"
side_a_ipv4_address: "{{ wfo_trunk.iptrunk.iptrunk_ipv4_network | ansible.utils.ipaddr('net') | ansible.utils.ipaddr('address') }}/31"
side_a_ipv6_address: "{{ wfo_trunk.iptrunk.iptrunk_ipv6_network | ansible.utils.ipaddr('net') | ansible.utils.ipaddr('1') | ansible.utils.ipaddr('address') }}/126"
side_b_ipv4_address: "{{ wfo_trunk.iptrunk.iptrunk_ipv4_network | ansible.utils.ipaddr('net') | ansible.utils.ipaddr('1') | ansible.utils.ipaddr('address') }}/31"
side_b_ipv6_address: "{{ wfo_trunk.iptrunk.iptrunk_ipv6_network | ansible.utils.ipaddr('net') | ansible.utils.ipaddr('2') | ansible.utils.ipaddr('address') }}/126"
old_node: "{{ wfo_trunk.iptrunk.iptrunk_sides[replace_index|int].iptrunk_side_node.router_fqdn }}"
new_side:
id: "{{ wfo_trunk.iptrunk.geant_s_sid }}"
description: "{{ wfo_trunk.iptrunk.iptrunk_description }}"
speed: "{{ wfo_trunk.iptrunk.iptrunk_speed }}"
is_leased_line: false ## Fix it to use iptrunk_type
isis_metric: "{{ wfo_trunk.iptrunk.iptrunk_isis_metric }}"
minimum_links: "{{ wfo_trunk.iptrunk.iptrunk_minimum_links }}"
name: "{{ wfo_trunk.iptrunk.iptrunk_sides[replace_index|int].iptrunk_side_node.router_fqdn }}"
router_access_via_ts: "{{ wfo_trunk.iptrunk.iptrunk_sides[replace_index|int].iptrunk_side_node.router_access_via_ts }}"
loopback: "{{ wfo_trunk.iptrunk.iptrunk_sides[replace_index|int].iptrunk_side_node.router_lo_ipv4_address }}"
ae_name: "{{ new_lag_interface }}"
members: "{{ new_lag_member_interfaces }}"
members_descriptions: "{{ wfo_trunk.iptrunk.iptrunk_sides[replace_index|int].iptrunk_side_ae_members_description }}"
port_sid: "{{ wfo_trunk.iptrunk.iptrunk_sides[replace_index|int].iptrunk_side_ae_geant_a_sid }}"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment