Skip to content

Commit 318c7dd

Browse files
authored
Fortinet - Getting rid of configuration task lists (ipspace#2864)
1 parent af96b59 commit 318c7dd

File tree

8 files changed

+173
-143
lines changed

8 files changed

+173
-143
lines changed

docs/caveats.md

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -291,13 +291,12 @@ Netlab enables VRRPv3 by default on Dell OS10, overriding any platform defaults.
291291
* You have to build the *dnsmasq* container image with the **netlab clab build dnsmasq** command.
292292

293293
(caveats-fortios)=
294-
## Fortinet FortiOS 6.x/7.0
294+
## Fortinet FortiOS
295295

296-
* FortiOS VM images have a default 15-day evaluation license. The VM has [limited capabilities](https://docs.fortinet.com/document/fortigate-private-cloud/7.2.0/kvm-administration-guide/504166/fortigate-vm-evaluation-license) without a license file. It will work for 15 days from the first boot, at which point you must install a license file or recreate the vagrant box completely from scratch.
297-
* The 15-day evaluation license only allows one single VDOM. Using the **netlab_vdom** node parameter will fail when using the built-in 15-day license.
298-
* _netlab_ configures Fortinet devices with API calls using username/password authentication. The last FortiGate images known to work with that restriction are software releases 7.0.x and 7.2.0. Later releases block API calls without a permanent evaluation license and require token-based authentication once API starts to work.
299296
* Use a recent version of Ansible and **fortinet.fortios** Ansible Galaxy collection (version 2.3.6 or later)
300-
* To troubleshoot API authentication, log into the FortiOS VM with **netlab connect** or **vagrant ssh** and enable HTTP debugging with the following commands:
297+
* _netlab_ tries to configure Fortinet devices with configuration scripts uploaded through the FortiOS Monitor API calls using username/password authentication.
298+
* If the API call fails, _netlab_ tries to push the configuration to a Fortinet device through a regular SSH session. Use **netlab initial -vvv --limit _fw_device_** to troubleshoot the configuration download (Ansible displays full contents of the SSH session at this level of verbosity).
299+
* To troubleshoot API authentication, log into the FortiOS VM with **netlab connect** and enable HTTP debugging with the following commands:
301300

302301
```
303302
diag debug enable
@@ -309,19 +308,19 @@ diag debug application httpsd -1
309308
* We're not testing Fortinet implementation as part of the regular integration tests; the configuration scripts might be outdated. If you encounter a problem, please open an issue.
310309
```
311310

312-
## Fortinet FortiOS 7.4.x/7.6.x
311+
### Fortinet FortiOS 6.x/7.0
312+
313+
* FortiOS VM images have a default 15-day evaluation license. The VM has [limited capabilities](https://docs.fortinet.com/document/fortigate-private-cloud/7.2.0/kvm-administration-guide/504166/fortigate-vm-evaluation-license) without a license file. It will work for 15 days from the first boot, at which point you must install a license file or recreate the vagrant box completely from scratch.
314+
* The 15-day evaluation license only allows one single VDOM. Using the **netlab_vdom** node parameter will fail when using the built-in 15-day license.
315+
316+
### Fortinet FortiOS 7.4.x/7.6.x
313317

314318
* Starting from FortiOS 7.2, FortiGate devices do not come with a license out of the box. Users can link *one* device with a permanent evaluation license to an account on the Fortinet support portal.
315319
* The license needs to be added before creating the Vagrant box.
316320
* There are restrictions associated with the evaluation license, including a maximum of three interfaces, firewall policies, and routes... For more detailed information, refer to the [evaluation license restrictions](https://docs.fortinet.com/document/fortigate/7.6.3/administration-guide/441460).
317321
* The license is linked to the serial number of the device and the UUID. To ensure that the serial number remains consistent each time you start the lab, set the `libvirt.uuid` (or `clab.env.FORTIGATE_UUID`) node parameter to the appropriate value.
318-
* MTU can be defined on the interface level, default is forced to 1500 bytes due to a different behaviour between `7.4.8` and `7.6.3` releases.
319-
* If you want to use a multi-vdom configuration, you just need to set the `netlab_vdom: <name>` in the node data. `root` vdom will be used as the management with interface `port1`, everything else will be configured in the specified traffic vdom. Default is `netlab_vdom: root` vdom in a no-vdom configuration.
320-
321-
### OSPF Caveats
322-
323-
* Fortinet implementation of OSPF configuration module does not implement per-interface OSPF areas. All interfaces belong to the OSPF area defined in the node data.
324-
* Fortinet configuration templates set OSPF network type based on number of neighbors, not based on **ospf.network_type** link/interface parameter.
322+
* MTU can be defined on the interface level, the default is forced to 1500 bytes due to a different behaviour between `7.4.8` and `7.6.3` releases.
323+
* If you want to use a multi-vdom configuration, you just need to set the `netlab_vdom: <name>` in the node data. `root` vdom will be used as the management with interface `port1`, and everything else will be configured in the specified traffic vdom. Default is `netlab_vdom: root` vdom in a no-vdom configuration.
325324

326325
(caveats-frr)=
327326
## FRRouting

docs/platforms.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ Ansible playbooks included with **netlab** can deploy and collect device configu
187187
| Cisco Nexus OS |||
188188
| Cumulus Linux |||
189189
| Dell OS10 ||||
190-
| Fortinet FortiOS || |
190+
| Fortinet FortiOS || |
191191
| FRR |[](caveats-frr) |[](caveats-frr) |
192192
| Generic Linux |||
193193
| Junos[^Junos] |||
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
- block:
2+
- name: "fortios_monitor: deploying {{ netsim_action }} from {{ config_template }}"
3+
fortinet.fortios.fortios_monitor:
4+
selector: upload.system.config-script
5+
params:
6+
filename: set_initial_config
7+
file_content: "{{ lookup('template', config_template) | b64encode }}"
8+
tags: [ print_action, always ]
9+
rescue:
10+
- name: "FortiOS CLI: deploying {{ netsim_action }} from {{ config_template }}"
11+
delegate_to: localhost
12+
ansible.builtin.expect:
13+
command: >-
14+
sshpass -p '{{ ansible_ssh_pass }}'
15+
ssh -o UserKnownHostsFile=/dev/null
16+
-o StrictHostKeyChecking=no
17+
{{ ansible_user }}@{{ ansible_host }}
18+
responses:
19+
'.*#': "{{ lookup('template', config_template) }}\nexit\n"
20+
tags: [ print_action, always ]

netsim/ansible/tasks/fortinet.fortios.fortios/initial.yml

Lines changed: 2 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -51,88 +51,5 @@
5151
name: "{{ netlab_vdom }}"
5252
when: netlab_vdom_is_enabled
5353

54-
- name: Configure global attributes
55-
fortinet.fortios.fortios_system_global:
56-
vdom: "{{ netlab_vdom }}"
57-
system_global:
58-
hostname: '{{ inventory_hostname.replace("_","-") }}'
59-
60-
- name: Turn off LLDP on management interface
61-
fortinet.fortios.fortios_system_interface:
62-
vdom: "{{ vdom }}"
63-
state: "present"
64-
system_interface:
65-
interface: "{{ mgmt_if }}"
66-
lldp_reception: "disable"
67-
lldp_transmission: "disable"
68-
name: "{{ mgmt_if }}"
69-
70-
- name: Configure loopback interface
71-
fortinet.fortios.fortios_system_interface:
72-
vdom: "{{ netlab_vdom }}"
73-
state: "present"
74-
system_interface:
75-
interface: "loopback0"
76-
ip: "{{ loopback.ipv4 | default(omit) }}"
77-
name: "loopback0"
78-
type: "loopback"
79-
vdom: "{{ netlab_vdom }}"
80-
allowaccess: "ping"
81-
when: loopback is defined
82-
83-
- name: Configure loopback ipv6 address
84-
fortinet.fortios.fortios_system_interface:
85-
vdom: "{{ netlab_vdom }}"
86-
state: "present"
87-
system_interface:
88-
interface: "loopback0"
89-
ipv6:
90-
ip6_address: "{{ loopback.ipv6 }}"
91-
ip6_mode: "static"
92-
name: "loopback0"
93-
vdom: "{{ netlab_vdom }}"
94-
when: loopback.ipv6 is defined
95-
96-
- name: Configure physical interfaces
97-
fortinet.fortios.fortios_system_interface:
98-
vdom: "{{ netlab_vdom }}"
99-
state: "present"
100-
system_interface:
101-
alias: '{{ interface.name.replace(">","-") | default(omit) }}'
102-
estimated_upstream_bandwidth: "{{ interface.bandwidth | default(omit) }}"
103-
estimated_downstream_bandwidth: "{{ interface.bandwidth | default(omit) }}"
104-
interface: "{{ interface.ifname }}"
105-
ip: "{{ interface.ipv4 | default(omit) }}"
106-
lldp_reception: "enable"
107-
lldp_transmission: "enable"
108-
mode: "static"
109-
mtu: "{{ interface.mtu | default(mtu) }}"
110-
mtu_override: "enable"
111-
name: "{{ interface.ifname }}"
112-
macaddr: "52:dc:ca:fe:{{ id }}:{{ interface.ifindex }}"
113-
type: "physical"
114-
vdom: "{{ netlab_vdom }}"
115-
allowaccess: "ping"
116-
with_items: "{{ interfaces }}"
117-
when: interface.ifname != "{{ mgmt_if }}"
118-
loop_control:
119-
loop_var: interface
120-
121-
- name: Configure interface ipv6 addresses
122-
fortinet.fortios.fortios_system_interface:
123-
vdom: "{{ netlab_vdom }}"
124-
state: "present"
125-
system_interface:
126-
interface: "{{ interface.ifname }}"
127-
ipv6:
128-
ip6_address: "{{ interface.ipv6 }}"
129-
ip6_mode: "static"
130-
ip6_allowaccess: "ping"
131-
ip6_send_adv: "enable"
132-
ra_send_mtu: "enable"
133-
name: "{{ interface.ifname }}"
134-
vdom: "{{ netlab_vdom }}"
135-
with_items: "{{ interfaces }}"
136-
when: interface.ipv6 is defined
137-
loop_control:
138-
loop_var: interface
54+
- name: Deploy initial configuration from template
55+
include_tasks: tasks/deploy-config/fortinet.fortios.fortios.yml

netsim/ansible/tasks/fortinet.fortios.fortios/ospf.yml

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
{% set vdom_traffic = netlab_vdom|default(vdom) %}
2+
{% set multi_vdom = vdom_traffic != vdom %}
3+
4+
{% if multi_vdom %}
5+
config global
6+
{% endif %}
7+
config system global
8+
set hostname {{ inventory_hostname.replace("_","-") }}
9+
end
10+
11+
config system interface
12+
edit "{{ mgmt_if }}"
13+
set vdom "{{ vdom }}"
14+
set lldp-transmission disable
15+
set lldp-reception disable
16+
set allowaccess ping https ssh http fgfm
17+
next
18+
{% if loopback is defined %}
19+
edit "{{ loopback.ifname }}"
20+
set vdom "{{ vdom_traffic }}"
21+
set status up
22+
set type loopback
23+
{% if loopback.ipv4 is defined %}
24+
set ip {{ loopback.ipv4 }}
25+
set allowaccess ping https ssh http fgfm
26+
{% endif %}
27+
{% if loopback.ipv6 is defined %}
28+
config ipv6
29+
set ip6-address {{ loopback.ipv6|upper }}
30+
set ip6-mode static
31+
set ip6-allowaccess ping https ssh http fgfm
32+
end
33+
{% endif %}
34+
next
35+
{% endif %}
36+
{% for interface in interfaces %}
37+
{% if interface.ifname != mgmt_if %}
38+
edit "{{ interface.ifname }}"
39+
set vdom "{{ vdom_traffic }}"
40+
set status up
41+
set lldp-reception enable
42+
set lldp-transmission enable
43+
set allowaccess ping
44+
# set macaddr "52:dc:ca:fe:{{ id }}:{{ interface.ifindex }}"
45+
set mode static
46+
{% if interface.ipv4 is defined %}
47+
set ip {{ interface.ipv4 }}
48+
{% endif %}
49+
{% if interface.mtu is defined %}
50+
set mtu-override enable
51+
set mtu {{ interface.mtu }}
52+
{% elif mtu is defined %}
53+
set mtu-override enable
54+
set mtu {{ mtu }}
55+
{% endif %}
56+
{% if interface.ipv6 is defined %}
57+
config ipv6
58+
set ip6-address {{ interface.ipv6|upper }}
59+
set ip6-mode static
60+
set ip6-allowaccess ping
61+
set ip6-send-adv enable
62+
end
63+
{% endif %}
64+
next
65+
{% endif %}
66+
{% endfor %}
67+
end
68+
69+
{% if multi_vdom %}
70+
end
71+
{% endif %}
Lines changed: 63 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,68 @@
1-
{% macro ospf_intf(intf) %}
2-
- name: {{ intf.ifname }}
3-
interface: {{ intf.ifname }}
4-
{% if intf.ospf.network_type|default('') == 'point-to-point' %}
5-
network_type: "point-to-point"
6-
{% endif %}
7-
{% if intf.ospf.cost is defined %}
8-
cost: {{ intf.ospf.cost }}
9-
{% endif %}
10-
{% endmacro %}
11-
---
12-
router_id: "{{ ospf.router_id }}"
13-
{% if ospf.reference_bandwidth is defined %}
14-
auto_cost_ref_bandwidth: "{{ ospf.reference_bandwidth }}"
1+
{% set vdom_traffic = netlab_vdom|default(vdom) %}
2+
{% set multi_vdom = vdom_traffic != vdom %}
3+
4+
{% if multi_vdom %}
5+
config vdom
6+
edit {{ vdom_traffic }}
157
{% endif %}
168

17-
{% for intf in netlab_interfaces if 'ospf' in intf and not ospf.passive|default(False) %}
18-
{% if loop.first %}
19-
ospf_interface:
20-
{% endif %}
21-
{{ ospf_intf(intf) }}
22-
{% endfor %}
9+
config router ospf
10+
set router-id {{ ospf.router_id }}
11+
{% if ospf.reference_bandwidth is defined %}
12+
set auto-cost-ref-bandwidth {{ ospf.reference_bandwidth }}
13+
{% endif %}
14+
{% set passive_intfs = netlab_interfaces|selectattr('ospf', 'defined')|selectattr('ospf.passive', 'defined')|selectattr('ospf.passive')|map(attribute='ifname')|list %}
15+
{% if passive_intfs|length > 0 %}
16+
set passive-interface {{ passive_intfs|join(' ') }}
17+
{% endif %}
18+
{% if netlab_interfaces|selectattr('ospf', 'defined')|list|length > 0 %}
19+
20+
config ospf-interface
21+
{% for intf in netlab_interfaces if 'ospf' in intf %}
22+
edit "{{ intf.ifname }}"
23+
set interface "{{ intf.ifname }}"
24+
{% if intf.ospf.network_type is defined %}
25+
set network-type {{ intf.ospf.network_type }}
26+
{% endif %}
27+
{% if intf.ospf.cost is defined %}
28+
set cost {{ intf.ospf.cost }}
29+
{% endif %}
30+
{% if intf.ospf.timers.hello is defined %}
31+
set hello-interval {{ intf.ospf.timers.hello }}
32+
{% endif %}
33+
{% if intf.ospf.timers.dead is defined %}
34+
set dead-interval {{ intf.ospf.timers.dead }}
35+
{% endif %}
36+
{% if intf.ospf.priority is defined %}
37+
set priority {{ intf.ospf.priority }}
38+
{% endif %}
39+
{% if intf.ospf.password is defined %}
40+
set authentication text
41+
set authentication-key {{ intf.ospf.password }}
42+
{% endif %}
43+
set status enable
44+
next
45+
{% endfor %}
46+
end
47+
{% endif %}
2348

24-
{% for intf in netlab_interfaces if 'ospf' in intf and ospf.passive|default(False) %}
25-
{% if loop.first %}
26-
passive_interface:
27-
{% endif %}
28-
{{ ospf_intf(intf) }}
29-
{% endfor %}
49+
config area
50+
{% for area in netlab_interfaces|map(attribute='ospf.area',default='')|unique if area %}
51+
edit {{ area }}
52+
next
53+
{% endfor %}
54+
end
3055

31-
area:
32-
{% for area in netlab_interfaces|map(attribute='ospf.area',default='')|unique if area %}
33-
- id: "{{ area }}"
34-
{% endfor %}
56+
config network
57+
{% for intf in netlab_interfaces if intf.ospf.area is defined %}
58+
edit {{ intf.ifindex }}
59+
set prefix {{ intf.ipv4|ipaddr('subnet') }}
60+
set area {{ intf.ospf.area }}
61+
next
62+
{% endfor %}
63+
end
64+
end
3565

36-
network:
37-
{% for intf in netlab_interfaces if intf.ospf.area is defined %}
38-
- area: {{ intf.ospf.area }}
39-
id: {{ intf.ifindex|default(0) }}
40-
prefix: {{ intf.ipv4|ipaddr('subnet') }}
41-
{% endfor %}
66+
{% if multi_vdom %}
67+
end
68+
{% endif %}

netsim/devices/fortios.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@ group_vars:
3232
ansible_httpapi_validate_certs: no
3333
ansible_httpapi_port: 80
3434
netlab_console_connection: ssh
35-
netlab_skip_missing_template: True
36-
netlab_config_tasks: True
3735
external:
3836
image: none
3937
features:
40-
ospf: True
38+
ospf:
39+
password: true
40+
priority: true
41+
timers: true
4142
graphite.icon: firewall

0 commit comments

Comments
 (0)