From 84ddea8fcbb4c8cb34849c51aeff5d32ed510130 Mon Sep 17 00:00:00 2001 From: Aleksandr Kurbatov <ak@geant.org> Date: Tue, 10 Dec 2024 19:11:31 +0000 Subject: [PATCH 01/11] bgp_base.j2: fixed typo from refactoring --- .../roles/bc_templates/routers/nokia/router/bgp_base.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geant/gap_ansible/roles/bc_templates/routers/nokia/router/bgp_base.j2 b/geant/gap_ansible/roles/bc_templates/routers/nokia/router/bgp_base.j2 index 5a5fd629..b7d3270c 100644 --- a/geant/gap_ansible/roles/bc_templates/routers/nokia/router/bgp_base.j2 +++ b/geant/gap_ansible/roles/bc_templates/routers/nokia/router/bgp_base.j2 @@ -21,7 +21,7 @@ {% endif %} {% if bgp_base_obj.error_handling is defined %} <error-handling> - <{{ bgp_base_obj.error_handling }}>true</{{ pe_bgp_base.error_handling }}> + <{{ bgp_base_obj.error_handling }}>true</{{ bgp_base_obj.error_handling }}> </error-handling> {% endif %} {% if bgp_base_obj.next_hop_resolution.shortcut_tunnel is defined %} -- GitLab From 1dee13f9625dcc657d53ea735aefc0f7577a89aa Mon Sep 17 00:00:00 2001 From: Aleksandr Kurbatov <ak@geant.org> Date: Tue, 10 Dec 2024 19:11:57 +0000 Subject: [PATCH 02/11] bgp_group.j2: make group.type optional --- .../roles/bc_templates/routers/nokia/router/bgp_group.j2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/geant/gap_ansible/roles/bc_templates/routers/nokia/router/bgp_group.j2 b/geant/gap_ansible/roles/bc_templates/routers/nokia/router/bgp_group.j2 index 3f1162e3..a9e3eb70 100644 --- a/geant/gap_ansible/roles/bc_templates/routers/nokia/router/bgp_group.j2 +++ b/geant/gap_ansible/roles/bc_templates/routers/nokia/router/bgp_group.j2 @@ -11,7 +11,9 @@ {% if group.nhs is defined %} <next-hop-self>{{ group.nhs }}</next-hop-self> {% endif %} + {% if group.type is defined %} <type>{{ group.type }}</type> + {% endif %} {% if group.bfd_liveness is defined %} <bfd-liveness>{{ group.bfd_liveness }}</bfd-liveness> {% endif %} -- GitLab From 431cfb2c69268354ed14867466523c6d13801245 Mon Sep 17 00:00:00 2001 From: Aleksandr Kurbatov <ak@geant.org> Date: Tue, 10 Dec 2024 19:14:42 +0000 Subject: [PATCH 03/11] Add new `ip_prefix_lists` role --- .../roles/ip_prefix_lists/README.md | 38 +++++++++ .../roles/ip_prefix_lists/defaults/main.yml | 2 + .../roles/ip_prefix_lists/handlers/main.yml | 2 + .../roles/ip_prefix_lists/meta/main.yml | 35 ++++++++ .../roles/ip_prefix_lists/tasks/compile.yaml | 15 ++++ .../roles/ip_prefix_lists/tasks/main.yml | 9 ++ .../templates/ip_prefix_list.j2 | 84 +++++++++++++++++++ .../roles/ip_prefix_lists/vars/main.yml | 2 + 8 files changed, 187 insertions(+) create mode 100644 geant/gap_ansible/roles/ip_prefix_lists/README.md create mode 100644 geant/gap_ansible/roles/ip_prefix_lists/defaults/main.yml create mode 100644 geant/gap_ansible/roles/ip_prefix_lists/handlers/main.yml create mode 100644 geant/gap_ansible/roles/ip_prefix_lists/meta/main.yml create mode 100644 geant/gap_ansible/roles/ip_prefix_lists/tasks/compile.yaml create mode 100644 geant/gap_ansible/roles/ip_prefix_lists/tasks/main.yml create mode 100644 geant/gap_ansible/roles/ip_prefix_lists/templates/ip_prefix_list.j2 create mode 100644 geant/gap_ansible/roles/ip_prefix_lists/vars/main.yml diff --git a/geant/gap_ansible/roles/ip_prefix_lists/README.md b/geant/gap_ansible/roles/ip_prefix_lists/README.md new file mode 100644 index 00000000..225dd44b --- /dev/null +++ b/geant/gap_ansible/roles/ip_prefix_lists/README.md @@ -0,0 +1,38 @@ +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). diff --git a/geant/gap_ansible/roles/ip_prefix_lists/defaults/main.yml b/geant/gap_ansible/roles/ip_prefix_lists/defaults/main.yml new file mode 100644 index 00000000..97666bcf --- /dev/null +++ b/geant/gap_ansible/roles/ip_prefix_lists/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# defaults file for ip_prefix_listrs diff --git a/geant/gap_ansible/roles/ip_prefix_lists/handlers/main.yml b/geant/gap_ansible/roles/ip_prefix_lists/handlers/main.yml new file mode 100644 index 00000000..b885d67b --- /dev/null +++ b/geant/gap_ansible/roles/ip_prefix_lists/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for ip_prefix_listrs diff --git a/geant/gap_ansible/roles/ip_prefix_lists/meta/main.yml b/geant/gap_ansible/roles/ip_prefix_lists/meta/main.yml new file mode 100644 index 00000000..36d899dd --- /dev/null +++ b/geant/gap_ansible/roles/ip_prefix_lists/meta/main.yml @@ -0,0 +1,35 @@ +galaxy_info: + author: A. Kurbatov + description: GEANT Orchestration and Automation Team + company: GEANT + + # 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: MIT + + min_ansible_version: '2.10' + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + galaxy_tags: + - network + # 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. diff --git a/geant/gap_ansible/roles/ip_prefix_lists/tasks/compile.yaml b/geant/gap_ansible/roles/ip_prefix_lists/tasks/compile.yaml new file mode 100644 index 00000000..41e7087f --- /dev/null +++ b/geant/gap_ansible/roles/ip_prefix_lists/tasks/compile.yaml @@ -0,0 +1,15 @@ +--- +- name: Set ansible host to localhost to compile template + ansible.builtin.set_fact: + ansible_host: "localhost" + ansible_connection: local + +- name: Print the template in "/var/tmp/ansible_run_{{ opid }}/IP_PREFIX_LISTS.conf" + # when: verb in ["deploy", "update", "terminate"] + ansible.builtin.template: + src: "ip_prefix_list.j2" + dest: "/var/tmp/ansible_run_{{ opid }}/IP_PREFIX_LISTS.conf" + lstrip_blocks: true + trim_blocks: true + mode: '0755' + delegate_to: localhost diff --git a/geant/gap_ansible/roles/ip_prefix_lists/tasks/main.yml b/geant/gap_ansible/roles/ip_prefix_lists/tasks/main.yml new file mode 100644 index 00000000..c0a10276 --- /dev/null +++ b/geant/gap_ansible/roles/ip_prefix_lists/tasks/main.yml @@ -0,0 +1,9 @@ +--- +# tasks file for ip_prefix_listrs +- name: Load Standard VRF IP prefix lists + when: subscription.product.product_type == 'VRF' + ansible.builtin.set_fact: + final_ip_prefix_lists: "{{ lookup('community.general.merge_variables', 'STANDARD_VRF_IP_PREFIX_LISTS') }}" + +- name: Include compile tasks for IP prefix lists + ansible.builtin.include_tasks: compile.yaml diff --git a/geant/gap_ansible/roles/ip_prefix_lists/templates/ip_prefix_list.j2 b/geant/gap_ansible/roles/ip_prefix_lists/templates/ip_prefix_list.j2 new file mode 100644 index 00000000..aa58f3d0 --- /dev/null +++ b/geant/gap_ansible/roles/ip_prefix_lists/templates/ip_prefix_list.j2 @@ -0,0 +1,84 @@ +<filter xmlns="urn:nokia.com:sros:ns:yang:sr:conf" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nokia-attr="urn:nokia.com:sros:ns:yang:sr:attributes"> + <match-list> + {% for ip_prefix in final_ip_prefix_lists %} + {% if ip_prefix.ipv4_prefixes is defined %} + {% if ip_prefix.alu_operation is defined %} + <ip-prefix-list alu:operation="{{ ip_prefix.alu_operation }}"> + {% else %} + <ip-prefix-list alu:operation="replace"> + {% endif %} + <prefix-list-name>{{ ip_prefix.name }}</prefix-list-name> + {% if ip_prefix.description is defined %} + <description>{{ ip_prefix.description }}</description> + {% endif %} + {% for ipv4_prefix in ip_prefix.ipv4_prefixes %} + <prefix> + <ip-prefix>{{ ipv4_prefix.prefix }}</ip-prefix> + </prefix> + {% endfor %} + </ip-prefix-list> + {% endif %} + {% if ip_prefix.ipv6_prefixes is defined %} + {% if ip_prefix.alu_operation is defined %} + <ipv6-prefix-list alu:operation="{{ ip_prefix.alu_operation }}"> + {% else %} + <ipv6-prefix-list alu:operation="replace"> + {% endif %} + <prefix-list-name>{{ ip_prefix.name }}</prefix-list-name> + {% if ip_prefix.description is defined %} + <description>{{ ip_prefix.description }}</description> + {% endif %} + {% for ipv6_prefix in ip_prefix.ipv6_prefixes %} + <prefix> + <ipv6-prefix>{{ ipv6_prefix.prefix }}</ipv6-prefix> + </prefix> + {% endfor %} + </ipv6-prefix-list> + {% endif %} + {% if ip_prefix.ipv4_apply_path is defined %} + {% if ip_prefix.alu_operation is defined %} + <ip-prefix-list alu:operation="{{ ip_prefix.alu_operation }}"> + {% else %} + <ip-prefix-list alu:operation="replace"> + {% endif %} + <prefix-list-name>{{ ip_prefix.name }}</prefix-list-name> + {% if ip_prefix.description is defined %} + <description>{{ ip_prefix.description }}</description> + {% endif %} + <apply-path> + {% for ap in ip_prefix.ipv4_apply_path %} + <bgp-peers> + <criterion-index>{{ ap.idx }}</criterion-index> + <group>{{ ap.bgp_group }}</group> + <neighbor>{{ ap.bgp_neighbor }}</neighbor> + <router-instance>{{ ap.router_instance }}</router-instance> + </bgp-peers> + {% endfor %} + </apply-path> + </ip-prefix-list> + {% endif %} + {% if ip_prefix.ipv6_apply_path is defined %} + {% if ip_prefix.alu_operation is defined %} + <ipv6-prefix-list alu:operation="{{ ip_prefix.alu_operation }}"> + {% else %} + <ipv6-prefix-list alu:operation="replace"> + {% endif %} + <prefix-list-name>{{ ip_prefix.name }}</prefix-list-name> + {% if ip_prefix.description is defined %} + <description>{{ ip_prefix.description }}</description> + {% endif %} + <apply-path> + {% for ap in ip_prefix.ipv6_apply_path %} + <bgp-peers> + <criterion-index>{{ ap.idx }}</criterion-index> + <group>{{ ap.bgp_group }}</group> + <neighbor>{{ ap.bgp_neighbor }}</neighbor> + <router-instance>{{ ap.router_instance }}</router-instance> + </bgp-peers> + {% endfor %} + </apply-path> + </ipv6-prefix-list> + {% endif %} + {% endfor %} + </match-list> +</filter> diff --git a/geant/gap_ansible/roles/ip_prefix_lists/vars/main.yml b/geant/gap_ansible/roles/ip_prefix_lists/vars/main.yml new file mode 100644 index 00000000..2fe5e9b5 --- /dev/null +++ b/geant/gap_ansible/roles/ip_prefix_lists/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for ip_prefix_listrs -- GitLab From 12db7924024c8f5f0db77c62641415aef510aa37 Mon Sep 17 00:00:00 2001 From: Aleksandr Kurbatov <ak@geant.org> Date: Tue, 10 Dec 2024 19:15:39 +0000 Subject: [PATCH 04/11] Role rename: `prefix_lists` -> `po_prefix_lists` --- .../gap_ansible/roles/{prefix_lists => po_prefix_lists}/README.md | 0 .../roles/{prefix_lists => po_prefix_lists}/defaults/main.yml | 0 .../roles/{prefix_lists => po_prefix_lists}/handlers/main.yml | 0 .../roles/{prefix_lists => po_prefix_lists}/meta/main.yml | 0 .../tasks/deploy_prefix_lists.yaml | 0 .../roles/{prefix_lists => po_prefix_lists}/tasks/main.yml | 0 .../templates/juniper/prefix-lists.j2 | 0 .../templates/nokia/prefix_lists.j2 | 0 .../roles/{prefix_lists => po_prefix_lists}/vars/main.yml | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename geant/gap_ansible/roles/{prefix_lists => po_prefix_lists}/README.md (100%) rename geant/gap_ansible/roles/{prefix_lists => po_prefix_lists}/defaults/main.yml (100%) rename geant/gap_ansible/roles/{prefix_lists => po_prefix_lists}/handlers/main.yml (100%) rename geant/gap_ansible/roles/{prefix_lists => po_prefix_lists}/meta/main.yml (100%) rename geant/gap_ansible/roles/{prefix_lists => po_prefix_lists}/tasks/deploy_prefix_lists.yaml (100%) rename geant/gap_ansible/roles/{prefix_lists => po_prefix_lists}/tasks/main.yml (100%) rename geant/gap_ansible/roles/{prefix_lists => po_prefix_lists}/templates/juniper/prefix-lists.j2 (100%) rename geant/gap_ansible/roles/{prefix_lists => po_prefix_lists}/templates/nokia/prefix_lists.j2 (100%) rename geant/gap_ansible/roles/{prefix_lists => po_prefix_lists}/vars/main.yml (100%) diff --git a/geant/gap_ansible/roles/prefix_lists/README.md b/geant/gap_ansible/roles/po_prefix_lists/README.md similarity index 100% rename from geant/gap_ansible/roles/prefix_lists/README.md rename to geant/gap_ansible/roles/po_prefix_lists/README.md diff --git a/geant/gap_ansible/roles/prefix_lists/defaults/main.yml b/geant/gap_ansible/roles/po_prefix_lists/defaults/main.yml similarity index 100% rename from geant/gap_ansible/roles/prefix_lists/defaults/main.yml rename to geant/gap_ansible/roles/po_prefix_lists/defaults/main.yml diff --git a/geant/gap_ansible/roles/prefix_lists/handlers/main.yml b/geant/gap_ansible/roles/po_prefix_lists/handlers/main.yml similarity index 100% rename from geant/gap_ansible/roles/prefix_lists/handlers/main.yml rename to geant/gap_ansible/roles/po_prefix_lists/handlers/main.yml diff --git a/geant/gap_ansible/roles/prefix_lists/meta/main.yml b/geant/gap_ansible/roles/po_prefix_lists/meta/main.yml similarity index 100% rename from geant/gap_ansible/roles/prefix_lists/meta/main.yml rename to geant/gap_ansible/roles/po_prefix_lists/meta/main.yml diff --git a/geant/gap_ansible/roles/prefix_lists/tasks/deploy_prefix_lists.yaml b/geant/gap_ansible/roles/po_prefix_lists/tasks/deploy_prefix_lists.yaml similarity index 100% rename from geant/gap_ansible/roles/prefix_lists/tasks/deploy_prefix_lists.yaml rename to geant/gap_ansible/roles/po_prefix_lists/tasks/deploy_prefix_lists.yaml diff --git a/geant/gap_ansible/roles/prefix_lists/tasks/main.yml b/geant/gap_ansible/roles/po_prefix_lists/tasks/main.yml similarity index 100% rename from geant/gap_ansible/roles/prefix_lists/tasks/main.yml rename to geant/gap_ansible/roles/po_prefix_lists/tasks/main.yml diff --git a/geant/gap_ansible/roles/prefix_lists/templates/juniper/prefix-lists.j2 b/geant/gap_ansible/roles/po_prefix_lists/templates/juniper/prefix-lists.j2 similarity index 100% rename from geant/gap_ansible/roles/prefix_lists/templates/juniper/prefix-lists.j2 rename to geant/gap_ansible/roles/po_prefix_lists/templates/juniper/prefix-lists.j2 diff --git a/geant/gap_ansible/roles/prefix_lists/templates/nokia/prefix_lists.j2 b/geant/gap_ansible/roles/po_prefix_lists/templates/nokia/prefix_lists.j2 similarity index 100% rename from geant/gap_ansible/roles/prefix_lists/templates/nokia/prefix_lists.j2 rename to geant/gap_ansible/roles/po_prefix_lists/templates/nokia/prefix_lists.j2 diff --git a/geant/gap_ansible/roles/prefix_lists/vars/main.yml b/geant/gap_ansible/roles/po_prefix_lists/vars/main.yml similarity index 100% rename from geant/gap_ansible/roles/prefix_lists/vars/main.yml rename to geant/gap_ansible/roles/po_prefix_lists/vars/main.yml -- GitLab From 53b3eea89ea0b18a9a5f4e210d14118c5afce68f Mon Sep 17 00:00:00 2001 From: Aleksandr Kurbatov <ak@geant.org> Date: Tue, 10 Dec 2024 19:17:42 +0000 Subject: [PATCH 05/11] `policy_options` role: adapt to VRF --- .../roles/policy_options/tasks/compile.yaml | 4 +- .../roles/policy_options/tasks/main.yml | 11 ++- .../tasks/merge_geant_ip_vars.yaml | 83 +++++++++++++++++ .../policy_options/tasks/merge_vars.yaml | 93 ------------------- .../policy_options/tasks/merge_vrf_vars.yaml | 8 ++ .../templates/policy_options.j2 | 18 ++-- 6 files changed, 112 insertions(+), 105 deletions(-) create mode 100644 geant/gap_ansible/roles/policy_options/tasks/merge_geant_ip_vars.yaml delete mode 100644 geant/gap_ansible/roles/policy_options/tasks/merge_vars.yaml create mode 100644 geant/gap_ansible/roles/policy_options/tasks/merge_vrf_vars.yaml diff --git a/geant/gap_ansible/roles/policy_options/tasks/compile.yaml b/geant/gap_ansible/roles/policy_options/tasks/compile.yaml index 6414d2ba..81eeb405 100644 --- a/geant/gap_ansible/roles/policy_options/tasks/compile.yaml +++ b/geant/gap_ansible/roles/policy_options/tasks/compile.yaml @@ -4,11 +4,11 @@ ansible_host: "localhost" ansible_connection: local -- name: Print the template in "/var/tmp/ansible_run_{{ opid }}/{{ partner_name }}_po.conf" +- name: Print the template in "/var/tmp/ansible_run_{{ opid }}/PO.conf" # when: verb in ["deploy", "update", "terminate"] ansible.builtin.template: src: "policy_options.j2" - dest: "/var/tmp/ansible_run_{{ opid }}/{{ partner_name }}_po.conf" + dest: "/var/tmp/ansible_run_{{ opid }}/PO.conf" lstrip_blocks: true trim_blocks: true mode: '0755' diff --git a/geant/gap_ansible/roles/policy_options/tasks/main.yml b/geant/gap_ansible/roles/policy_options/tasks/main.yml index 4fbe967f..a896fc3b 100644 --- a/geant/gap_ansible/roles/policy_options/tasks/main.yml +++ b/geant/gap_ansible/roles/policy_options/tasks/main.yml @@ -1,7 +1,16 @@ --- # tasks file for policy_options - name: Load Standard Policy Statements vars - ansible.builtin.include_tasks: merge_vars.yaml + when: > + subscription.product.product_type == "L3CoreService" + and + subscription.l3_core_service_type in ["GÉANT IP", "GEANT IP", "GEANT_IP"] + ansible.builtin.include_tasks: merge_geant_ip_vars.yaml + +- name: Load Standard Policy Options for VRF {{ subscription.vrf.vrf_name }} + when: > + subscription.product.product_type == "VRF" + ansible.builtin.include_tasks: merge_vrf_vars.yaml - name: Compile templates ansible.builtin.include_tasks: compile.yaml diff --git a/geant/gap_ansible/roles/policy_options/tasks/merge_geant_ip_vars.yaml b/geant/gap_ansible/roles/policy_options/tasks/merge_geant_ip_vars.yaml new file mode 100644 index 00000000..7f82e838 --- /dev/null +++ b/geant/gap_ansible/roles/policy_options/tasks/merge_geant_ip_vars.yaml @@ -0,0 +1,83 @@ +--- +- name: Merge NREN standard policies V4 + ansible.builtin.set_fact: + standard_nren_policies_v4: "{{ lookup('community.general.merge_variables', 'STANDARD_PO_POL_STATEMENTS_V4') }}" + +- name: Merge NREN standard policies v6 + ansible.builtin.set_fact: + standard_nren_policies_v6: "{{ lookup('community.general.merge_variables', 'STANDARD_PO_POL_STATEMENTS_V6') }}" + +- name: Set NREN community name + ansible.builtin.set_fact: + nren_community_names: ["GEANT_{{ partner_name | upper }}", "GEANT_{{ partner_name | upper }}_BLOCK"] + +- name: Set NREN community value (2-byte ASN) + when: (partner.asn | int) < 65536 + ansible.builtin.set_fact: + nren_community_values: ["{{ geant_re_as_number }}:{{ partner.asn }}", "{{ bgp.block_community_prefix }}:{{ partner.asn }}"] + +- name: Set NREN community value (4-byte ASN) + when: (partner.asn | int) > 65535 + ansible.builtin.set_fact: + nren_community_values: ["origin:{{ partner.asn }}:{{ geant_re_as_number }}", "origin:{{ partner.asn }}:{{ block_community_prefix }}"] + +- name: Create a list of NREN communities + ansible.builtin.set_fact: + po_final_communities: "{{ nren_po_communities | default([]) + [ {'name': item.0, 'member': item.1} ] }}" + loop: "{{ nren_community_names | zip(nren_community_values) | list }}" + +- name: Set BGP V4 session object + ansible.builtin.set_fact: + bgp_session_v4: "{{ ap.sbp | json_query(query) }}" + vars: + query: "bgp_session_list[?ip_type == 'ipv4'] | [0]" + +- name: Set BGP V6 session object + ansible.builtin.set_fact: + bgp_session_v6: "{{ ap.sbp | json_query(query) }}" + vars: + query: "bgp_session_list[?ip_type == 'ipv6'] | [0]" + +- name: Select Custom V4 policies if specified by GSO + when: >- + bgp_session_v4.has_custom_policies | ansible.builtin.bool + ansible.builtin.set_fact: + custom_nren_policies_v4: "{{ lookup('community.general.merge_variables', 'CUSTOM_PO_POL_STATEMENTS_V4') }}" + +- name: Select Custom V6 policies if specified by GSO + when: >- + bgp_session_v6.has_custom_policies | ansible.builtin.bool + ansible.builtin.set_fact: + custom_nren_policies_v6: "{{ lookup('community.general.merge_variables', 'CUSTOM_PO_POL_STATEMENTS_V6') }}" + +- name: Combine policies when V4 is custom and V6 is standard + when: > + bgp_session_v4.has_custom_policies | ansible.builtin.bool + and + not bgp_session_v6.has_custom_policies | ansible.builtin.bool + ansible.builtin.set_fact: + po_final_policies: "{{ [custom_nren_policies_v4, standard_nren_policies_v6] | community.general.lists_mergeby('name') }}" + +- name: Combine policies when V4 is custom and V6 is custom + when: > + bgp_session_v4.has_custom_policies | ansible.builtin.bool + and + bgp_session_v6.has_custom_policies | ansible.builtin.bool + ansible.builtin.set_fact: + po_final_policies: "{{ [custom_nren_policies_v4, custom_nren_policies_v6] | community.general.lists_mergeby('name') }}" + +- name: Combine policies when V4 is standard and V6 is custom + when: > + not bgp_session_v4.has_custom_policies | ansible.builtin.bool + and + bgp_session_v6.has_custom_policies | ansible.builtin.bool + ansible.builtin.set_fact: + po_final_policies: "{{ [standard_nren_policies_v4, custom_nren_policies_v6] | community.general.lists_mergeby('name') }}" + +- name: Combine policies when V4 is standard and V6 is standard + when: > + not bgp_session_v4.has_custom_policies | ansible.builtin.bool + and + not bgp_session_v6.has_custom_policies | ansible.builtin.bool + ansible.builtin.set_fact: + po_final_policies: "{{ [standard_nren_policies_v4, standard_nren_policies_v6] | community.general.lists_mergeby('name') }}" diff --git a/geant/gap_ansible/roles/policy_options/tasks/merge_vars.yaml b/geant/gap_ansible/roles/policy_options/tasks/merge_vars.yaml deleted file mode 100644 index f4bfd77a..00000000 --- a/geant/gap_ansible/roles/policy_options/tasks/merge_vars.yaml +++ /dev/null @@ -1,93 +0,0 @@ ---- -- name: Prepare Policy vars for L3 Core Service with standard filters - when: >- - subscription.product.product_type == "L3CoreService" - and - subscription.l3_core_service_type == "GÉANT IP" - block: - - name: Merge NREN standard policies V4 - ansible.builtin.set_fact: - standard_nren_policies_v4: "{{ lookup('community.general.merge_variables', 'STANDARD_PO_POL_STATEMENTS_V4') }}" - - - name: Merge NREN standard policies v6 - ansible.builtin.set_fact: - standard_nren_policies_v6: "{{ lookup('community.general.merge_variables', 'STANDARD_PO_POL_STATEMENTS_V6') }}" - - - name: Set NREN community name - ansible.builtin.set_fact: - nren_community_names: ["GEANT_{{ partner_name | upper }}", "GEANT_{{ partner_name | upper }}_BLOCK"] - - - name: Set NREN community value (2-byte ASN) - when: (partner.asn | int) < 65536 - ansible.builtin.set_fact: - nren_community_values: ["{{ geant_re_as_number }}:{{ partner.asn }}", "{{ bgp.block_community_prefix }}:{{ partner.asn }}"] - - - name: Set NREN community value (4-byte ASN) - when: (partner.asn | int) > 65535 - ansible.builtin.set_fact: - nren_community_values: ["origin:{{ partner.asn }}:{{ geant_re_as_number }}", "origin:{{ partner.asn }}:{{ block_community_prefix }}"] - - - name: Create a list of NREN communities - ansible.builtin.set_fact: - nren_po_communities: "{{ nren_po_communities | default([]) + [ {'name': item.0, 'member': item.1} ] }}" - loop: "{{ nren_community_names | zip(nren_community_values) | list }}" - -- name: Set BGP V4 session object - ansible.builtin.set_fact: - bgp_session_v4: "{{ ap.sbp | json_query(query) }}" - vars: - query: "bgp_session_list[?ip_type == 'ipv4'] | [0]" - -- name: Set BGP V6 session object - ansible.builtin.set_fact: - bgp_session_v6: "{{ ap.sbp | json_query(query) }}" - vars: - query: "bgp_session_list[?ip_type == 'ipv6'] | [0]" - -- name: Select Custom V4 policies if specified by GSO - when: >- - bgp_session_v4.has_custom_policies | ansible.builtin.bool - ansible.builtin.set_fact: - custom_nren_policies_v4: "{{ lookup('community.general.merge_variables', 'CUSTOM_PO_POL_STATEMENTS_V4') }}" - -- name: Select Custom V6 policies if specified by GSO - when: >- - bgp_session_v6.has_custom_policies | ansible.builtin.bool - ansible.builtin.set_fact: - custom_nren_policies_v6: "{{ lookup('community.general.merge_variables', 'CUSTOM_PO_POL_STATEMENTS_V6') }}" - -- name: Combine policies when V4 is custom and V6 is standard - when: > - bgp_session_v4.has_custom_policies | ansible.builtin.bool - and - not bgp_session_v6.has_custom_policies | ansible.builtin.bool - ansible.builtin.set_fact: - nren_policies: "{{ [custom_nren_policies_v4, standard_nren_policies_v6] | community.general.lists_mergeby('name') }}" - -- name: Combine policies when V4 is custom and V6 is custom - when: > - bgp_session_v4.has_custom_policies | ansible.builtin.bool - and - bgp_session_v6.has_custom_policies | ansible.builtin.bool - ansible.builtin.set_fact: - nren_policies: "{{ [custom_nren_policies_v4, custom_nren_policies_v6] | community.general.lists_mergeby('name') }}" - -- name: Combine policies when V4 is standard and V6 is custom - when: > - not bgp_session_v4.has_custom_policies | ansible.builtin.bool - and - bgp_session_v6.has_custom_policies | ansible.builtin.bool - ansible.builtin.set_fact: - nren_policies: "{{ [standard_nren_policies_v4, custom_nren_policies_v6] | community.general.lists_mergeby('name') }}" - -- name: Combine policies when V4 is standard and V6 is standard - when: > - not bgp_session_v4.has_custom_policies | ansible.builtin.bool - and - not bgp_session_v6.has_custom_policies | ansible.builtin.bool - ansible.builtin.set_fact: - nren_policies: "{{ [standard_nren_policies_v4, standard_nren_policies_v6] | community.general.lists_mergeby('name') }}" - -- name: Debug final nren_policies - ansible.builtin.debug: - var: nren_policies diff --git a/geant/gap_ansible/roles/policy_options/tasks/merge_vrf_vars.yaml b/geant/gap_ansible/roles/policy_options/tasks/merge_vrf_vars.yaml new file mode 100644 index 00000000..528a7b45 --- /dev/null +++ b/geant/gap_ansible/roles/policy_options/tasks/merge_vrf_vars.yaml @@ -0,0 +1,8 @@ +--- +- name: Load Standard Policy Options prefix lists for VRF {{ subscription.vrf.vrf_name }} + ansible.builtin.set_fact: + po_final_prefix_lists: "{{ lookup('community.general.merge_variables', 'STANDARD_VRF_PO_PREFIX_LISTS') }}" + +- name: Load Standard Policy Options policies for VRF {{ subscription.vrf.vrf_name }} + ansible.builtin.set_fact: + po_final_policies: "{{ lookup('community.general.merge_variables', 'STANDARD_VRF_PO_POLICIES') }}" diff --git a/geant/gap_ansible/roles/policy_options/templates/policy_options.j2 b/geant/gap_ansible/roles/policy_options/templates/policy_options.j2 index 47e5933d..0b06d46a 100644 --- a/geant/gap_ansible/roles/policy_options/templates/policy_options.j2 +++ b/geant/gap_ansible/roles/policy_options/templates/policy_options.j2 @@ -4,15 +4,15 @@ {% endif %} <policy-options xmlns="urn:nokia.com:sros:ns:yang:sr:conf" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nokia-attr="urn:nokia.com:sros:ns:yang:sr:attributes"> - {# {% if nokia_po_prefix_lists is defined %} #} - {# {% with prefix_lists_obj=nokia_po_prefix_lists %} #} - {# {% include 'policy_options/prefix_lists.j2' %} #} - {# {% endwith %} #} - {# {% endif %} #} + {% if po_final_prefix_lists is defined %} + {% with prefix_lists_obj=po_final_prefix_lists %} + {% include 'prefix_lists.j2' %} + {% endwith %} + {% endif %} {# Communities #} - {% if nren_po_communities is defined %} - {% with communities_obj=nren_po_communities %} + {% if po_final_communities is defined %} + {% with communities_obj=po_final_communities %} {% include 'communities.j2' %} {% endwith %} {% endif %} @@ -25,8 +25,8 @@ {# {% endif %} #} {# Policy statements #} - {% if nren_policies is defined %} - {% with policy_obj=nren_policies %} + {% if po_final_policies is defined %} + {% with policy_obj=po_final_policies %} {% include 'policy_statements.j2' %} {% endwith %} {% endif %} -- GitLab From db11916205119b697bf6b78524c406425d63e7e2 Mon Sep 17 00:00:00 2001 From: Aleksandr Kurbatov <ak@geant.org> Date: Tue, 10 Dec 2024 19:18:22 +0000 Subject: [PATCH 06/11] Add new `vrf` role --- geant/gap_ansible/roles/vrf/README.md | 38 +++++++++++++++++++ geant/gap_ansible/roles/vrf/defaults/main.yml | 2 + geant/gap_ansible/roles/vrf/meta/main.yml | 35 +++++++++++++++++ .../gap_ansible/roles/vrf/tasks/compile.yaml | 15 ++++++++ geant/gap_ansible/roles/vrf/tasks/main.yml | 20 ++++++++++ geant/gap_ansible/roles/vrf/templates/router | 1 + .../roles/vrf/templates/service.j2 | 7 ++++ geant/gap_ansible/roles/vrf/vars/main.yml | 3 ++ 8 files changed, 121 insertions(+) create mode 100644 geant/gap_ansible/roles/vrf/README.md create mode 100644 geant/gap_ansible/roles/vrf/defaults/main.yml create mode 100644 geant/gap_ansible/roles/vrf/meta/main.yml create mode 100644 geant/gap_ansible/roles/vrf/tasks/compile.yaml create mode 100644 geant/gap_ansible/roles/vrf/tasks/main.yml create mode 120000 geant/gap_ansible/roles/vrf/templates/router create mode 100644 geant/gap_ansible/roles/vrf/templates/service.j2 create mode 100644 geant/gap_ansible/roles/vrf/vars/main.yml diff --git a/geant/gap_ansible/roles/vrf/README.md b/geant/gap_ansible/roles/vrf/README.md new file mode 100644 index 00000000..225dd44b --- /dev/null +++ b/geant/gap_ansible/roles/vrf/README.md @@ -0,0 +1,38 @@ +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). diff --git a/geant/gap_ansible/roles/vrf/defaults/main.yml b/geant/gap_ansible/roles/vrf/defaults/main.yml new file mode 100644 index 00000000..11b78b78 --- /dev/null +++ b/geant/gap_ansible/roles/vrf/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# defaults file for vrf diff --git a/geant/gap_ansible/roles/vrf/meta/main.yml b/geant/gap_ansible/roles/vrf/meta/main.yml new file mode 100644 index 00000000..36d899dd --- /dev/null +++ b/geant/gap_ansible/roles/vrf/meta/main.yml @@ -0,0 +1,35 @@ +galaxy_info: + author: A. Kurbatov + description: GEANT Orchestration and Automation Team + company: GEANT + + # 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: MIT + + min_ansible_version: '2.10' + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + galaxy_tags: + - network + # 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. diff --git a/geant/gap_ansible/roles/vrf/tasks/compile.yaml b/geant/gap_ansible/roles/vrf/tasks/compile.yaml new file mode 100644 index 00000000..52832206 --- /dev/null +++ b/geant/gap_ansible/roles/vrf/tasks/compile.yaml @@ -0,0 +1,15 @@ +--- +- name: Set ansible host to localhost to compile template + ansible.builtin.set_fact: + ansible_host: "localhost" + ansible_connection: local + +- name: Print the template in "/var/tmp/ansible_run_{{ opid }}/VRF.conf" + # when: verb in ["deploy", "update", "terminate"] + ansible.builtin.template: + src: "service.j2" + dest: "/var/tmp/ansible_run_{{ opid }}/VRF.conf" + lstrip_blocks: true + trim_blocks: true + mode: '0755' + delegate_to: localhost diff --git a/geant/gap_ansible/roles/vrf/tasks/main.yml b/geant/gap_ansible/roles/vrf/tasks/main.yml new file mode 100644 index 00000000..7718ab3a --- /dev/null +++ b/geant/gap_ansible/roles/vrf/tasks/main.yml @@ -0,0 +1,20 @@ +--- +# tasks file for policy_options +# - name: Load Standard Policy Statements vars +# when: > +# subscription.product.product_type == "L3CoreService" +# and +# subscription.l3_core_service_type in ["GÉANT IP", "GEANT IP", "GEANT_IP"] +# ansible.builtin.include_tasks: merge_geant_ip_vars.yaml +# +# - name: Load Standard Policy Options for VRF {{ subscription.vrf.vrf_name }} +# when: > +# subscription.product.product_type == "VRF" +# ansible.builtin.include_tasks: merge_vrf_vars.yaml +# +- name: Compile templates + ansible.builtin.include_tasks: compile.yaml + +- name: Deploy templates if standalone run + when: is_standalone_run | ansible.builtin.bool + ansible.builtin.include_tasks: deploy_vrf.yaml diff --git a/geant/gap_ansible/roles/vrf/templates/router b/geant/gap_ansible/roles/vrf/templates/router new file mode 120000 index 00000000..b578eecd --- /dev/null +++ b/geant/gap_ansible/roles/vrf/templates/router @@ -0,0 +1 @@ +../../bc_templates/routers/nokia/router \ No newline at end of file diff --git a/geant/gap_ansible/roles/vrf/templates/service.j2 b/geant/gap_ansible/roles/vrf/templates/service.j2 new file mode 100644 index 00000000..66a591cd --- /dev/null +++ b/geant/gap_ansible/roles/vrf/templates/service.j2 @@ -0,0 +1,7 @@ + +<service xmlns="urn:nokia.com:sros:ns:yang:sr:conf" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:nokia-attr="urn:nokia.com:sros:ns:yang:sr:attributes"> +{% with pe_vprns=LHCONE_VPRN %} +{% include 'router/vprn.j2' %} +{% endwith %} +</service> + diff --git a/geant/gap_ansible/roles/vrf/vars/main.yml b/geant/gap_ansible/roles/vrf/vars/main.yml new file mode 100644 index 00000000..5937b210 --- /dev/null +++ b/geant/gap_ansible/roles/vrf/vars/main.yml @@ -0,0 +1,3 @@ +--- +# vars file for vrf +is_standalone_run: false -- GitLab From 16c07506c59542e3c1706f0a90c2f1ddc0717a13 Mon Sep 17 00:00:00 2001 From: Aleksandr Kurbatov <ak@geant.org> Date: Tue, 10 Dec 2024 19:19:25 +0000 Subject: [PATCH 07/11] `deploy_service_config`: adapt to work with `vrf_update` --- .../gap_ansible/roles/deploy_service_config/tasks/main.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/geant/gap_ansible/roles/deploy_service_config/tasks/main.yml b/geant/gap_ansible/roles/deploy_service_config/tasks/main.yml index cfb638df..0330f464 100644 --- a/geant/gap_ansible/roles/deploy_service_config/tasks/main.yml +++ b/geant/gap_ansible/roles/deploy_service_config/tasks/main.yml @@ -5,6 +5,12 @@ # The "delegate_to" works as expected in conjuction with "import_tasks". # However, mixing "imports" with "includes" is not recommended. # Another way is to "apply" the "delegate_to: localhost". +- name: Set router and vendor for the use with SBP + when: subscription.product.product_type == 'L3CoreService' + ansible.builtin.set_fact: + router: "{{ ap.sbp.edge_port.node }}" + vendor: "{{ router.vendor }}" + - name: Assemble the config from fragments in previous roles ansible.builtin.include_tasks: assemble_config.yml -- GitLab From f05f21de3b25e3f2ac2c031bfb1e5491ff1efc09 Mon Sep 17 00:00:00 2001 From: Aleksandr Kurbatov <ak@geant.org> Date: Tue, 10 Dec 2024 19:19:42 +0000 Subject: [PATCH 08/11] vrf_update playbook --- geant/gap_ansible/playbooks/vrf_update.yaml | 47 +++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 geant/gap_ansible/playbooks/vrf_update.yaml diff --git a/geant/gap_ansible/playbooks/vrf_update.yaml b/geant/gap_ansible/playbooks/vrf_update.yaml new file mode 100644 index 00000000..99abbd3d --- /dev/null +++ b/geant/gap_ansible/playbooks/vrf_update.yaml @@ -0,0 +1,47 @@ +--- +- name: Update VRF + hosts: all + gather_facts: false + tasks: + - name: Generate an ID for this run + ansible.builtin.set_fact: + opid: "{{ lookup('community.general.random_string', length=18, special=false) }}" + + - name: Print the ID + ansible.builtin.debug: + msg: "{{ opid }}" + + - name: Create a folder for all compiled output + ansible.builtin.file: + path: "/var/tmp/ansible_run_{{ opid }}" + state: directory + mode: '0755' + delegate_to: localhost + + - name: Import group_vars/all + ansible.builtin.include_vars: + dir: /opt/ansible_inventory/group_vars/all + + - name: Import standard variables for "{{ subscription.product.product_type }}/{{ subscription.vrf.vrf_name | upper }}" + ansible.builtin.include_vars: + dir: /opt/ansible_inventory/geant_services/{{ subscription.product.product_type }}/{{ subscription.vrf.vrf_name | upper }} + + - name: Compile IP prefix lists + ansible.builtin.include_role: + name: ip_prefix_lists + + - name: Compile Policy Options config + ansible.builtin.include_role: + name: policy_options + + - name: Compile VRF config + ansible.builtin.include_role: + name: vrf + + - name: Assemble and deploy generated config + ansible.builtin.include_role: + name: deploy_service_config + loop: + "{{ subscription.vrf.vrf_router_list }}" + loop_control: + loop_var: router -- GitLab From 04c9c1339bc0b8ee0a53f30a4530da9adb3eb3fc Mon Sep 17 00:00:00 2001 From: Aleksandr Kurbatov <ak@geant.org> Date: Fri, 13 Dec 2024 11:41:12 +0000 Subject: [PATCH 09/11] `deploy_service`: set vars depending on the product_type --- .../roles/deploy_service_config/tasks/set_vars.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 geant/gap_ansible/roles/deploy_service_config/tasks/set_vars.yaml diff --git a/geant/gap_ansible/roles/deploy_service_config/tasks/set_vars.yaml b/geant/gap_ansible/roles/deploy_service_config/tasks/set_vars.yaml new file mode 100644 index 00000000..f6938b03 --- /dev/null +++ b/geant/gap_ansible/roles/deploy_service_config/tasks/set_vars.yaml @@ -0,0 +1,6 @@ +--- +- name: Set router and vendor for the use with SBP + when: subsciption.product.product_type == 'L3CoreService' + ansible.builtin.set_fact: + router: "{{ ap.sbp.edge_port.node }}" + vendor: "{{ router.vendor }}" -- GitLab From b65e9fb082ef4bd00367827a7f76b86dbb0689af Mon Sep 17 00:00:00 2001 From: Aleksandr Kurbatov <ak@geant.org> Date: Fri, 13 Dec 2024 11:43:57 +0000 Subject: [PATCH 10/11] role rename: `prefix_lists` -> `po_prefix_lists` --- geant/gap_ansible/playbooks/l3_core_service.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geant/gap_ansible/playbooks/l3_core_service.yaml b/geant/gap_ansible/playbooks/l3_core_service.yaml index d09db643..2223bb6c 100644 --- a/geant/gap_ansible/playbooks/l3_core_service.yaml +++ b/geant/gap_ansible/playbooks/l3_core_service.yaml @@ -81,7 +81,7 @@ block: - name: Include Prefix-list role ansible.builtin.include_role: - name: prefix_lists + name: po_prefix_lists loop: "{{ subscription.l3_core_service.ap_list }}" loop_control: -- GitLab From 954e9bc7971458f9733cb5d85bdcef481dc7f553 Mon Sep 17 00:00:00 2001 From: Aleksandr Kurbatov <ak@geant.org> Date: Fri, 13 Dec 2024 11:57:48 +0000 Subject: [PATCH 11/11] Cleanup VRF tasks --- geant/gap_ansible/roles/vrf/tasks/main.yml | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/geant/gap_ansible/roles/vrf/tasks/main.yml b/geant/gap_ansible/roles/vrf/tasks/main.yml index 7718ab3a..7c08c59d 100644 --- a/geant/gap_ansible/roles/vrf/tasks/main.yml +++ b/geant/gap_ansible/roles/vrf/tasks/main.yml @@ -1,20 +1,7 @@ --- -# tasks file for policy_options -# - name: Load Standard Policy Statements vars -# when: > -# subscription.product.product_type == "L3CoreService" -# and -# subscription.l3_core_service_type in ["GÉANT IP", "GEANT IP", "GEANT_IP"] -# ansible.builtin.include_tasks: merge_geant_ip_vars.yaml -# -# - name: Load Standard Policy Options for VRF {{ subscription.vrf.vrf_name }} -# when: > -# subscription.product.product_type == "VRF" -# ansible.builtin.include_tasks: merge_vrf_vars.yaml -# - name: Compile templates ansible.builtin.include_tasks: compile.yaml -- name: Deploy templates if standalone run - when: is_standalone_run | ansible.builtin.bool - ansible.builtin.include_tasks: deploy_vrf.yaml +# - name: Deploy templates if standalone run +# when: is_standalone_run | ansible.builtin.bool +# ansible.builtin.include_tasks: deploy_vrf.yaml -- GitLab