Skip to content
Snippets Groups Projects
Commit 10eb2ece authored by Aleksandr Kurbatov's avatar Aleksandr Kurbatov
Browse files

Merge branch 'feature/nat-697-sbp' into 'develop'

FW role finishing

See merge request !200
parents 2ea32c8d c626afe4
Branches
Tags
1 merge request!200FW role finishing
Pipeline #90786 passed
Showing
with 553 additions and 0 deletions
Role Name
=========
A role for configuring policy options stanza in Nokia SROS.
Requirements
------------
GEANT custom netconf module with Nokia "commit_comment" and "config_mode" features.
Role Variables
--------------
- vars/main.yaml
- external inventory (group_vars)
- orchestrator (GSO)
Dependencies
------------
n/a
Example Playbook
----------------
Role is supposed to be driven by GSO.
License
-------
MIT
Author Information
------------------
A. Kurbatov, S. Spinelli. GEANT Orchestration and Automation Team (GOAT).
---
# defaults file for policy_options
---
# handlers file for policy_options
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.
---
- 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 }}/{{ partner_name }}_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"
lstrip_blocks: true
trim_blocks: true
mode: '0755'
delegate_to: localhost
---
- name: Import variables from 'all'
ansible.builtin.include_vars:
dir: /opt/ansible_inventory/group_vars/all
- name: Set ansible_host to terminal server when router is offline
when: ap.sbp.edge_port.node.router_access_via_ts | ansible.builtin.bool
ansible.builtin.set_fact:
ansible_host: "{{ ap.sbp.edge_port.node.router_site.site_ts_address }}"
ansible_port: "{{ ap.sbp.edge_port.node.router_ts_port }}"
- name: Load netconf connection config
ansible.builtin.set_fact:
ansible_connection: "{{ netconf_access[ap.sbp.edge_port.node.vendor].ansible_connection }}"
ansible_network_os: "{{ netconf_access[ap.sbp.edge_port.node.vendor].ansible_network_os }}"
- name: Deploy PO config on "{{ inventory_hostname }}" [CHECK ONLY][NOKIA]
when: dry_run | ansible.builtin.bool
geant.gap_ansible.nokia_netconf_config:
format: xml
default_operation: merge
content: "{{ lookup('ansible.builtin.file', '/var/tmp/ansible_run_{{ opid }}/{{ partner_name }}_po.conf') }}"
commit: true
validate: true
config_mode: private
diff: true
register: output
check_mode: true
- name: Deploy PO config on "{{ inventory_hostname }}" [COMMIT][NOKIA]
when: not (dry_run | ansible.builtin.bool)
geant.gap_ansible.nokia_netconf_config:
format: xml
default_operation: merge
content: "{{ lookup('ansible.builtin.file', '/var/tmp/ansible_run_{{ opid }}/{{ partner_name }}_po.conf') }}"
commit: true
commit_comment: "{{ commit_comment }}"
config_mode: private
diff: true
register: output
check_mode: false
---
# tasks file for policy_options
- name: Load Standard Policy Statements vars
ansible.builtin.include_tasks: merge_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_po.yaml
---
- 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
{% for as_path in as_paths_obj %}
<as-path alu:operation="replace">
<name>{{ as_path.name }}</name>
<expression>{{ as_path.expression}}</expression>
</as-path>
{% endfor %}
{% for community in communities_obj %}
<community alu:operation="replace">
<name>{{ community.name }}</name>
<member>
<member>{{ community.member }}</member>
</member>
</community>
{% endfor %}
{% if is_standalone_run %}
<config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:alu="urn:ietf:params:xml:ns:netconf:base:1.0">
<configure xmlns="urn:nokia.com:sros:ns:yang:sr:conf">
{% 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 %} #}
{# Communities #}
{% if nren_po_communities is defined %}
{% with communities_obj=nren_po_communities %}
{% include 'communities.j2' %}
{% endwith %}
{% endif %}
{# AS paths #}
{# {% if nokia_po_as_paths is defined %} #}
{# {% with as_paths_obj=nokia_po_as_paths %} #}
{# {% include 'policy_options/as_paths.j2' %} #}
{# {% endwith %} #}
{# {% endif %} #}
{# Policy statements #}
{% if nren_policies is defined %}
{% with policy_obj=nren_policies %}
{% include 'policy_statements.j2' %}
{% endwith %}
{% endif %}
</policy-options>
{% if is_standalone_run %}
</configure>
</config>
{% endif %}
{% for pol in policy_obj %}
<policy-statement alu:operation="replace">
<name>{{ pol.name }}</name>
<entry-type>{{ pol.entry_type }}</entry-type>
{% for entry in pol.entries %}
{% if pol.entry_type == 'named' %}
<named-entry>
{% endif %}
<entry-name>{{ entry.name }}</entry-name>
{% if entry.from is defined %}
<from>
{% if entry.from.as_path is defined %}
<as-path>
{% if entry.from.as_path.name is defined %}
<name>{{ entry.from.as_path.name }}</name>
{% endif %}
{% if entry.from.as_path.length is defined %}
<length>
<value>{{ entry.from.as_path.length }}</value>
</length>
{% endif %}
</as-path>
{% endif %}
{% if entry.from.prefix_list is defined %}
{% for pl in entry.from.prefix_list %}
<prefix-list>{{ pl }}</prefix-list>
{% endfor %}
{% endif %}
{% if entry.from.policy is defined %}
<policy>{{ entry.from.policy }}</policy>
{% endif %}
{% if entry.from.community is defined %}
<community>
<name>{{ entry.from.community }}</name>
</community>
{% endif %}
{% if entry.from.origin_validation_state is defined %}
<origin-validation-state>{{ entry.from.origin_validation_state }}</origin-validation-state>
{% endif %}
{% if entry.from.protocol is defined %}
{% for proto in entry.from.protocol %}
<protocol>
<name>{{ proto }}</name>
</protocol>
{% endfor %}
{% endif %}
</from>
{% endif %}
<action>
<action-type>{{ entry.action_type }}</action-type>
{% if entry.action is defined %}
{% for action_item in entry.action %}
{% for act_k, act_v in action_item.items() %}
{% if act_k == "community_add" %}
{% for community in act_v %}
<community>
<add>{{ community }}</add>
</community>
{% endfor %}
{% elif act_k == "bgp_med" %}
<bgp-med>
<set>{{ act_v | default(bgp.standard_metric.med[ap_type]) }}</set>
</bgp-med>
{% elif act_k == "local_preference" %}
<local-preference>{{ act_v | default(bgp.standard_metric.loca_pref[ap_type]) }}</local-preference>
{% else %}
<{{ act_k | replace("_", "-") }}>{{ act_v }}</{{act_k | replace("_", "-") }}>
{% endif %}
{% endfor %}
{% endfor %}
{% endif %}
</action>
</named-entry>
{% endfor %}
</policy-statement>
{% endfor %}
{% for prefix_list in prefix_lists_obj %}
<prefix-list alu:operation="replace">
<name>{{ prefix_list.name }}</name>
{% for prefix in prefix_list.prefixes %}
<prefix>
<ip-prefix>{{ prefix.ip }}</ip-prefix>
<type>{{ prefix.type }}</type>
{% if prefix.type == 'range' %}
<start-length>{{ prefix.range_start_length }}</start-length>
<end-length>{{ prefix.range_end_length }}</end-length>
{% endif %}
</prefix>
{% endfor %}
</prefix-list>
{% endfor %}
---
# vars file for policy_options
is_standalone_run: false
site_name: "{{ ap.sbp.edge_port.node.router_site.site_name }}"
ap_type: "{{ ap.ap_type }}"
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).
---
# defaults file for prefix_lists
---
# handlers file for prefix_lists
galaxy_info:
author: Simone Spinelli, A. Kurbatov
description: Geant Orchestration and Automation Team
company: Geant
license: MIT
min_ansible_version: '2.10'
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.
collections:
- geant.gap_ansible
---
- name: Import variables from 'all'
ansible.builtin.include_vars:
dir: /opt/ansible_inventory/group_vars/all
- name: Set ansible_host to terminal server when router is offline
when: ap.sbp.edge_port.node.router_access_via_ts | ansible.builtin.bool
ansible.builtin.set_fact:
ansible_host: "{{ ap.sbp.edge_port.node.router_site.site_ts_address }}"
ansible_port: "{{ ap.sbp.edge_port.node.router_ts_port }}"
- name: Load netconf connection config
ansible.builtin.set_fact:
ansible_connection: "{{ netconf_access[ap.sbp.edge_port.node.vendor].ansible_connection }}"
ansible_network_os: "{{ netconf_access[ap.sbp.edge_port.node.vendor].ansible_network_os }}"
- name: Deploy FW config on "{{ inventory_hostname }}" [CHECK ONLY][NOKIA]
when: dry_run | ansible.builtin.bool
geant.gap_ansible.nokia_netconf_config:
format: xml
default_operation: merge
content: "{{ lookup('ansible.builtin.file', '/var/tmp/ansible_run_{{ opid }}/{{ partner_name }}_prefix_lists.conf') }}"
commit: true
validate: true
config_mode: private
diff: true
register: output
check_mode: true
- name: Deploy FW config on "{{ inventory_hostname }}" [COMMIT][NOKIA]
when: not (dry_run | ansible.builtin.bool)
geant.gap_ansible.nokia_netconf_config:
format: xml
default_operation: merge
content: "{{ lookup('ansible.builtin.file', '/var/tmp/ansible_run_{{ opid }}/{{ partner_name }}_prefix_lists.conf') }}"
commit: true
commit_comment: "{{ commit_comment }}"
config_mode: private
diff: true
register: output
check_mode: false
---
# tasks file for prefix_lists
- name: Collect prefixes and render the prefix template
delegate_to: localhost
block:
- name: Collect IPV4 routes from bgpq4
ansible.builtin.command: bgpq4 -j4 "{{ partner.as_set }}"
register: bgpq4_ipv4_routes_in_json
changed_when: true
- name: Convert IPV4 output to real json
ansible.builtin.set_fact:
ipv4_prefix_list_name: "{{ partner_name | upper }}_{{ partner.type }}_PREFIXES_IPV4"
routes: "{{ bgpq4_ipv4_routes_in_json.stdout | from_json }}"
- name: Fail if IPV4 routes list lenght is too short
when: routes.NN | length <= 1
ansible.builtin.meta: end_play
- name: Form IPV4 route object
ansible.builtin.set_fact:
bgpq4_ipv4_routes: "{{ bgpq4_ipv4_routes | default([]) + [item.prefix] }}"
loop: "{{ routes.NN }}"
- name: Collect IPV6 routes from bgpq4
ansible.builtin.command: bgpq4 -j6 "{{ partner.as_set }}"
register: bgpq4_ipv6_routes_in_json
changed_when: true
- name: Convert IPV6 outeput to real json
ansible.builtin.set_fact:
ipv6_prefix_list_name: "{{ partner_name | upper }}_{{ partner.type }}_PREFIXES_IPV6"
routes: "{{ bgpq4_ipv6_routes_in_json.stdout | from_json }}"
- name: Fail if IPV6 routes list lenght is too short
when: routes.NN | length <= 1
ansible.builtin.meta: end_play
- name: Form IPV6 route object
ansible.builtin.set_fact:
bgpq4_ipv6_routes: "{{ bgpq4_ipv6_routes | default([]) + [item.prefix] }}"
loop: "{{ routes.NN }}"
- name: Put everything together
ansible.builtin.set_fact:
nren_prefix_lists: "{{ nren_prefix_lists | default([]) + [{'name': ipv4_prefix_list_name, 'prefixes': bgpq4_ipv4_routes},
{'name': ipv6_prefix_list_name, 'prefixes': bgpq4_ipv6_routes}] }}"
- name: Print the template in "/var/tmp/ansible_run_{{ opid }}/{{ partner_name }}_prefix_lists.conf"
ansible.builtin.template:
src: "nokia/prefix_lists.j2"
dest: "/var/tmp/ansible_run_{{ opid }}/{{ partner_name }}_prefix_lists.conf"
lstrip_blocks: true
trim_blocks: true
mode: '0755'
- name: Include deploy if standalone run
when: is_standalone_run | ansible.builtin.bool
ansible.builtin.include_tasks: deploy_prefix_lists.yaml
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment