community.routeros icon indicating copy to clipboard operation
community.routeros copied to clipboard

[Question] How to make DHCP lease entry as static

Open Nerus87 opened this issue 11 months ago • 6 comments

As in the thread, how make an entry as a static DHCP lease by using API calls from Anisble?

Path: /ip/dhcp-server/lease -> make-static

Nerus87 avatar Dec 29 '24 15:12 Nerus87

You should be able to use the api_info module (https://docs.ansible.com/ansible/devel/collections/community/routeros/api_info_module.html with include_dynamic=true) and some Jinja to find the id of the entry you want to convert, and then use the api module (https://docs.ansible.com/ansible/devel/collections/community/routeros/api_module.html) to call make-static for that entry.

felixfontein avatar Dec 29 '24 16:12 felixfontein

I was able to find an entry by the host-name but only via SSH, in the current API host-name not existing.

#- name: Get {{ container_name }} mac-address
#  community.network.routeros_command:
#    commands: :put [/ip/dhcp-server/lease/ get ([find where host-name=srv-test]) mac-address]
#    register: mac_address
#  when: ansible_network_os == 'community.network.routeros'

Nerus87 avatar Dec 30 '24 19:12 Nerus87

Have you tried the unfiltered option of community.routeros.api_info?

felixfontein avatar Dec 30 '24 19:12 felixfontein

Have you tried the unfiltered option of community.routeros.api_info?

Yeah, this was a reason, sorry for not responding asap but still fighting with scripting. I was able to find it based on host-name (it was a mess and I spent the whole day to find the reason). So if you even have a problem with dashes in names use this site to check your query and save my time: https://mixedanalytics.com/tools/jmespath-expression-tester/

- name: Get DHCP lease list
  community.routeros.api_info:
    hostname: "{{ hostname }}"
    password: "{{ password }}"
    username: "{{ username }}"
    path: ip dhcp-server lease
    include_dynamic: true
    unfiltered: true
    hide_defaults: false
  register: leases

- name: Filter leases list and set lease id
  set_fact:
    lease_id: "{{ leases.result | json_query(query) }}"
  vars:
    query: "[?\"host-name\"== '{{ container_name }}'].\".id\""

I found a way how to change but it is not an "idempotent" (ansible detecting change even if it wasn't) way:

- name: Make DHCP lease static
  community.routeros.api:
    hostname: "{{ hostname }}"
    password: "{{ password }}"
    username: "{{ username }}"
    path: "ip dhcp-server lease"
    cmd: "make-static numbers={{ lease_id }}"

- name: Set DHCP lease to static and set IP with time
  community.routeros.api_find_and_modify:
    hostname: "{{ hostname }}"
    password: "{{ password }}"
    username: "{{ username }}"
    path: ip dhcp-server lease
    find:
      host-name: '{{ container_name }}'
    values:
      address: '{{ address }}'
      lease-time: '{{ dhcp_lease_time }}'

Nerus87 avatar Dec 31 '24 16:12 Nerus87

Why don't you use the restrict option of community.routeros.api_info to only return the entries where host-name equals container_name?

- name: Get DHCP lease list
  community.routeros.api_info:
    hostname: "{{ hostname }}"
    password: "{{ password }}"
    username: "{{ username }}"
    path: ip dhcp-server lease
    include_dynamic: true
    unfiltered: true
    hide_defaults: false
    restrict:
      - field: host-name
        values:
          - "{{ container_name }}"
  register: leases

Regarding the api task: why don't you only run it when the entry is actually dynamic?

- name: Make DHCP lease static
  community.routeros.api:
    hostname: "{{ hostname }}"
    password: "{{ password }}"
    username: "{{ username }}"
    path: "ip dhcp-server lease"
    cmd: "make-static numbers={{ leases.result[0]['.id'] }}"
  when: leases.result[0].dynamic

felixfontein avatar Jan 01 '25 08:01 felixfontein

Why don't you use the restrict option of community.routeros.api_info to only return the entries where host-name equals container_name?

- name: Get DHCP lease list
  community.routeros.api_info:
    hostname: "{{ hostname }}"
    password: "{{ password }}"
    username: "{{ username }}"
    path: ip dhcp-server lease
    include_dynamic: true
    unfiltered: true
    hide_defaults: false
    restrict:
      - field: host-name
        values:
          - "{{ container_name }}"
  register: leases

"msg": "restrict: the field "host-name" does not exist for this path" As I understand this was not a part of 'ip dhcp-server lease'

Regarding the api task: why don't you only run it when the entry is actually dynamic?

- name: Make DHCP lease static
  community.routeros.api:
    hostname: "{{ hostname }}"
    password: "{{ password }}"
    username: "{{ username }}"
    path: "ip dhcp-server lease"
    cmd: "make-static numbers={{ leases.result[0]['.id'] }}"
  when: leases.result[0].dynamic

I missed the dynamic field, thanks for pointing it out.

Nerus87 avatar Jan 01 '25 13:01 Nerus87