fortinet-ansible-dev / ansible-galaxy-fortios-collection

GNU General Public License v3.0
84 stars 47 forks source link

Question on usage - setting dhcp (v4) reservations #303

Open spikefishjohn opened 4 months ago

spikefishjohn commented 4 months ago

I have a series of Raspberry PIs that I'm deploying with ansible. All PIs are network booted. I want to know which host is on what IP so I came up with the follow playbook.

Is this the best way to do this? My question is really on how to manage the ID field under reserved_address. I'm currently using loop_control to get the index number from the group.

I don't like this, but I don't see a way around this unless I make a reservations group and use the position in that list globally across any dhcp server on the firewall. I guess another option would be to have more tasks that search through all the reservations, but then I also have to find where the next free ID is which seems like a pain. I also looked in the source (only a little) and it seems like ID is a required field for reserved_address.

Ideally, I wouldn't care what the ID is, I would just say this reservation should be present, but that doesn't seem to be an option unless I'm missing something? Any feedback is apricated.

BTW the amount of modules for Fortinet is really impressive.

- name: Setup DHCP Reservations
  hosts: fortigate
  collections:
    - fortinet.fortios
  vars_files:
    - vars.yml
  gather_facts: false
  tasks:
  - name: Get dhcp config for vlan
    fortinet.fortios.fortios_configuration_fact:
      vdom: root
      filters:
        - "interface=={{ pivlanname }}"
      selector: system.dhcp_server
      access_token: "{{ access_token }}"
    register: dhcp_facts

  - name: set dhcp reservations
    fortinet.fortios.fortios_system_dhcp_server:
      vdom: root
      state: present
      access_token: "{{ access_token }}"
      enable_log: true
      member_path: reserved_address:id
      member_state: present
      system_dhcp_server:
        id: "{{ dhcp_facts['meta']['results'][0]['id'] }}"
        reserved_address:
        - action: reserved
          description: "{{ item }}"
          ip: "{{ hostvars[item]['ansible_host'] }}"
          mac: "{{ hostvars[item]['mac'] }}"
          id: "{{ my_index + 1}}"
    when: dhcp_facts.meta.results[0]
    loop:
      "{{ groups['PIs'] }}"
    loop_control:
      index_var: my_index
spikefishjohn commented 4 months ago

BTW using ID 0 for system_dhcp_server fails with

"parameter system_dhcp_server.reserved_address.id is empty"

jantari commented 4 months ago

Looks like a good approach, from configuring DHCP reservations with ansible myself I think that you will run into errors when you remove a Pi, or even just reorder them (switch the position of two PIs in the inventory) because your loop will attempt to create duplicate MAC reservations which the FortiGate won't allow.

You also have the potential issue that if you just remove your last Pi, the last one in the list, your task will simply not loop over that anymore but it will therefore not remove the reservation you previously created.

spikefishjohn commented 3 months ago

yes removing a PI is a problem. I do need logic to find what shouldn't be there as well.

Feel its way to easy to create a race condition with this.

EDIT: make gooder english