Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 49 additions & 33 deletions netsim/ansible/tasks/fortios/initial.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,52 +3,68 @@
ansible.builtin.set_fact:
netlab_vdom_is_enabled: "{{ netlab_vdom is defined and netlab_vdom != vdom }}"

- name: Enable api-user authentication
block:
- name: Generate api-user token
delegate_to: localhost
expect:
command: >-
sshpass -p '{{ ansible_ssh_pass }}'
ssh -o UserKnownHostsFile=/dev/null
-o StrictHostKeyChecking=no
{{ ansible_user }}@{{ ansible_host }}
responses:
"password": "{{ ansible_ssh_pass }}"
"#":
- config global
- execute api-user generate-key netlab
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line fails as there is no api user netlab when I tested:

    "stdout_lines": [
        "Warning: Permanently added '10.194.59.11' (ECDSA) to the list of known hosts.",
        "",
        "FGVMxxxxxY5C # config global",
        "",
        "",
        "command parse error before 'global'",
        "Command fail. Return code 1",
        "",
        "FGVMxxxxxY5C # execute api-user generate-key netlab",
        "",
        "Could not find api-user netlab.",
        "Command fail. Return code -3",
        "",
        "FGVMxxxxxY5C # exit",
        "",
        "Connection to 10.194.59.11 closed."
    ]
}

If I manually configure the API user like this, it then works:

config system api-user
    edit "netlab"
        set accprofile "super_admin"
    next
end

And also (I would need to test further without having to do this step manually) it seems that I no longer need to wait 60s when configuring multi-vdom mode.

It's looking very good, we just need to add the api-user. Is this something you have built in as part of your vagrant box?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something you have built in as part of your vagrant box?

It should be part of vagrant-box if it was built with cloud-init image.
https://github.com/a-v-popov/netlab/blob/205a09a6cde536a3adbe2b781ae1bfb4ccaaeea5/netsim/install/libvirt/fortios/openstack/latest/user_data#L28

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, my issue is that I haven't used the cloud-init image to create my vagrant boxes.
I'd be keen to add the creation of the api-user netlab as part of the task

- exit
Comment on lines +16 to +26
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

      responses:
        "password": "{{ ansible_ssh_pass }}"
        "#":
        - config system api-user
        - edit "netlab"
        - set accprofile "super_admin"
        - next
        - end
        - config global
        - execute api-user generate-key netlab
        - exit

I've just tested with this, and I've got the famous: it works for me!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logically I do not see much difference between admin user and netlab api-user. If one is set in a vagrant box the other could be configured at the same time. Screen scraping works, but it has its drawbacks. On the other end of the spectrum one could prebuild the whole config including both both users and feed it via cloud-image along with a license. Or use admin-scp. But in any case API token is sort of a problem, because it is expendable.

In my setup API keys are generated by a licensing script, so intend to set netlab_generate_api_token: false for my workloads anyway.

register: raw_token

- name: Extract api-user token
set_fact:
ansible_httpapi_session_key:
access_token: "{{ raw_token.stdout | regex_search('New API key: (\\w+)', '\\1') | first }}"

- name: Create auth.yml in host_vars
delegate_to: localhost
copy:
dest: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}/auth.yml"
content: |
---
ansible_httpapi_session_key:
access_token: "{{ ansible_httpapi_session_key.access_token }}"
when: netlab_generate_api_token|default(true)

- name: Enable multi-VDOM mode if a traffic VDOM is defined
fortinet.fortios.fortios_system_global:
vdom: "{{ vdom }}"
system_global:
management_vdom: "{{ vdom }}"
vdom_mode: multi-vdom
hostname: '{{ inventory_hostname.replace("_","-") }}'
vdom_mode: "{{ 'multi-vdom' if netlab_vdom_is_enabled else 'no-vdom' }}"
register: vdom_mode_result
when: netlab_vdom_is_enabled

- name: Ensure FortiGate is ready after VDOM mode change
block:
- name: Wait 60 seconds after VDOM mode change
ansible.builtin.wait_for:
host: "{{ ansible_host }}"
port: 443
timeout: 180
sleep: 10 # time in seconds between checks
delay: 60 # Initial delay in seconds before first check
state: started
- name: Test FortiGate API readiness after VDOM mode change
fortinet.fortios.fortios_system_global:
vdom: "{{ vdom }}"
system_global:
hostname: '{{ inventory_hostname.replace("_","-") }}'
register: hostname_result
retries: 5
delay: 10 # Initial delay and waiting time between retries
until: hostname_result is not failed and hostname_result.meta.http_status == 200
when: >-
vdom_mode_result.meta is defined and
(vdom_mode_result.meta.http_status == 200 and vdom_mode_result.meta.revision_changed)
ansible.builtin.wait_for:
host: "{{ ansible_host }}"
port: 443
timeout: 180
sleep: 10 # time in seconds between checks
delay: "{{ netlab_vdom_timer|default(0) }}" # Initial delay in seconds before first check
state: started
when:
- netlab_vdom_timer|default(0) > 0
- vdom_mode_result.meta.http_status == 200
- vdom_mode_result.meta.revision_changed

- name: Ensure `{{ vdom }}` VDOM is set as admin
fortinet.fortios.fortios_system_settings:
vdom: "{{ vdom }}"
system_settings:
vdom_type: admin
when: netlab_vdom_is_enabled

- name: Configure `{{ netlab_vdom }}` virtual domain
fortinet.fortios.fortios_system_vdom:
vdom: "{{ vdom }}"
state: present
system_vdom:
name: "{{ netlab_vdom }}"
register: api_result
retries: "{{ netlab_check_retries | default(20) }}"
delay: "{{ netlab_check_delay | default(5) }}"
until: api_result.meta.http_status == 200
when: netlab_vdom_is_enabled

- name: Deploy initial configuration from template
Expand Down
30 changes: 16 additions & 14 deletions netsim/ansible/templates/initial/fortios.j2
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
config global
{% endif %}
config system global
set management-vdom {{vdom}}
set hostname {{ inventory_hostname.replace("_","-") }}
end

Expand All @@ -15,6 +16,20 @@ config system interface
set lldp-reception disable
set allowaccess ping https ssh http fgfm
next

{% if multi_vdom %}
end

end

{# End of `config global` #}

config vdom
edit {{ vdom_traffic }}

config system interface
{% endif %}

{% if loopback is defined %}
edit "{{ loopback.ifname }}"
set vdom "{{ vdom_traffic }}"
Expand Down Expand Up @@ -66,19 +81,7 @@ config system interface
{% endfor %}
end

{% if multi_vdom %}
end
{% endif %}

{# End of `config global` #}

{% if netlab_default_policy|default(false) %}

{% if multi_vdom %}
config vdom
edit {{ vdom_traffic }}
{% endif %}

config firewall policy
edit 1000
{% if not netlab_default_policy.enable|default(true) %}
Expand All @@ -97,9 +100,8 @@ config firewall policy
set logtraffic disable
next
end
{% endif %}

{% if multi_vdom %}
end
{% endif %}

{% endif %}
6 changes: 3 additions & 3 deletions netsim/devices/fortios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ group_vars:
vdom: "root"
netlab_vdom: "root"
mgmt_if: port1
ansible_httpapi_use_ssl: no
ansible_httpapi_validate_certs: no
ansible_httpapi_port: 80
ansible_httpapi_use_ssl: true
ansible_httpapi_validate_certs: false
ansible_httpapi_port: 443
netlab_console_connection: ssh
netlab_ready: [ ansible ]
netlab_device_type: fortios
Expand Down
Loading