如何使用Ansible ipaddr获取子网中的IP范围

如何使用Ansible ipaddr获取子网中的IP范围,ansible,Ansible,我有一个子网(即192.168.1.0/24),我需要从该子网获取前33个IP地址,以便使用os\u port模块在OpenStack中创建33个端口 目前,我将模块配置为: - name: reserve ports for {{ item.network }} os_port: state: present network: "{{ item.network }}" fixed_ips: - ip_address: "{{ item.ip }}"

我有一个子网(即192.168.1.0/24),我需要从该子网获取前33个IP地址,以便使用
os\u port
模块在OpenStack中创建33个端口

目前,我将模块配置为:

- name: reserve ports for {{ item.network }}
  os_port:
    state: present
    network: "{{ item.network }}"
    fixed_ips:
      - ip_address: "{{ item.ip }}"
  environment: "{{ openstack_environment_vars }}"
  loop: "{{ reserved_ips }}"
  run_once: true
它通过一个列表显示如下:

reserved_ips:
  - ip: 192.168.1.1
    network: test
  - ip: 192.168.1.2
    network: test
  - ip: 192.168.1.3
    network: test
  - ip: 192.168.1.4
这很好,但是,为了避免创建一个单独IP的长列表,我正在寻找一种方法来简化它

我已经查看了ipaddr,查看了一个子网并添加了所需的IP,但从中可以看出,我一次只能查询一个IP或一个子网。如何使用Ipaddr为我获取前33个IP

理想情况下,该计划将经历以下过程:

- name: reserve ports for {{ item.network }}
  os_port:
    state: present
    network: "{{ item.network }}"
    fixed_ips:
      - ip_address: "{{ cidr | ipaddr ('1-33') }}"
  environment: "{{ openstack_environment_vars }}"
  loop: "{{ reserved_ips }}"
  run_once: true
关于如何筛选前33个IP的任何建议?

一个选项是使用和

下面是剧本

- hosts: localhost
  tasks:
    - set_fact:
        sub1: "{{ sub1 | default([]) + [item | int] }}"
      with_sequence: start=1 end=3
    - set_fact:
        sub2: "{{ sub2 | default([]) + [item | int] }}"
      with_sequence: start=1 end=3

- hosts: localhost
  vars:
    reserved_ips:
      - cidr: 192.168.1
        network: test
        sub: "{{ sub1 }}"
      - cidr: 172.16.1
        network: test2
        sub: "{{ sub2 }}"
  tasks:
    - debug:
        msg: "ip:{{ item.0.cidr }}.{{ item.1 }} network:{{ item.0.network }}"
      with_subelements:
        - "{{ reserved_ips }}"
        - sub
给出:

"msg": "ip:192.168.1.1 network:test"
"msg": "ip:192.168.1.2 network:test"
"msg": "ip:192.168.1.3 network:test"
"msg": "ip:172.16.1.1 network:test2"
"msg": "ip:172.16.1.2 network:test2"
"msg": "ip:172.16.1.3 network:test2"
"msg": "ip:192.168.1.1 network:test"
"msg": "ip:192.168.1.2 network:test"
"msg": "ip:192.168.1.3 network:test"
剧本可以简化为

包含文件loop-task.yml

- debug:
    msg: "ip:{{ iitem.cidr|next_nth_usable(item|int) }} network:{{ iitem.network }}"
  with_sequence: "start={{ iitem.ip_start }} end={{ iitem.ip_end }}"
给出:

"msg": "ip:192.168.1.1 network:test"
"msg": "ip:192.168.1.2 network:test"
"msg": "ip:192.168.1.3 network:test"
"msg": "ip:172.16.1.1 network:test2"
"msg": "ip:172.16.1.2 network:test2"
"msg": "ip:172.16.1.3 network:test2"
"msg": "ip:192.168.1.1 network:test"
"msg": "ip:192.168.1.2 network:test"
"msg": "ip:192.168.1.3 network:test"

Ansible的
ipaddr
filter插件让生活变得不必要的复杂。通过编写自己的过滤器插件,您可以使您的生活更轻松。在剧本旁边创建一个
filter\u plugins
目录,并将以下内容放入
filter\u plugins/ipaddr\u extra.py

import netaddr


def filter_to_network(value):
    return netaddr.IPNetwork(value)


class FilterModule(object):
    filter_map = {
        'to_network': filter_to_network,
    }

    def filters(self):
        return self.filter_map
现在,您可以使用一个简单的切片操作从网络中选择前n个地址(在本例中,我选择每个网络上的前10个地址):

这会让我觉得:

PLAY [localhost] ******************************************************************************

TASK [debug] **********************************************************************************
ok: [localhost] => (item=example1/192.168.1.1) => {
    "msg": "reserve address 192.168.1.1 for network example1"
}
ok: [localhost] => (item=example1/192.168.1.2) => {
    "msg": "reserve address 192.168.1.2 for network example1"
}
ok: [localhost] => (item=example1/192.168.1.3) => {
    "msg": "reserve address 192.168.1.3 for network example1"
}
ok: [localhost] => (item=example1/192.168.1.4) => {
    "msg": "reserve address 192.168.1.4 for network example1"
}
ok: [localhost] => (item=example1/192.168.1.5) => {
    "msg": "reserve address 192.168.1.5 for network example1"
}
ok: [localhost] => (item=example1/192.168.1.6) => {
    "msg": "reserve address 192.168.1.6 for network example1"
}
ok: [localhost] => (item=example1/192.168.1.7) => {
    "msg": "reserve address 192.168.1.7 for network example1"
}
ok: [localhost] => (item=example1/192.168.1.8) => {
    "msg": "reserve address 192.168.1.8 for network example1"
}
ok: [localhost] => (item=example1/192.168.1.9) => {
    "msg": "reserve address 192.168.1.9 for network example1"
}
ok: [localhost] => (item=example2/192.168.2.1) => {
    "msg": "reserve address 192.168.2.1 for network example2"
}
ok: [localhost] => (item=example2/192.168.2.2) => {
    "msg": "reserve address 192.168.2.2 for network example2"
}
ok: [localhost] => (item=example2/192.168.2.3) => {
    "msg": "reserve address 192.168.2.3 for network example2"
}
ok: [localhost] => (item=example2/192.168.2.4) => {
    "msg": "reserve address 192.168.2.4 for network example2"
}
ok: [localhost] => (item=example2/192.168.2.5) => {
    "msg": "reserve address 192.168.2.5 for network example2"
}
ok: [localhost] => (item=example2/192.168.2.6) => {
    "msg": "reserve address 192.168.2.6 for network example2"
}
ok: [localhost] => (item=example2/192.168.2.7) => {
    "msg": "reserve address 192.168.2.7 for network example2"
}
ok: [localhost] => (item=example2/192.168.2.8) => {
    "msg": "reserve address 192.168.2.8 for network example2"
}
ok: [localhost] => (item=example2/192.168.2.9) => {
    "msg": "reserve address 192.168.2.9 for network example2"
}

PLAY RECAP ************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0   

很好的解决方案。我对过滤器做了一些调整,这样就不需要映射('string'):
def expand_iprange(value):return[str(ip)for netaddr.IPNetwork(value)]
PLAY [localhost] ******************************************************************************

TASK [debug] **********************************************************************************
ok: [localhost] => (item=example1/192.168.1.1) => {
    "msg": "reserve address 192.168.1.1 for network example1"
}
ok: [localhost] => (item=example1/192.168.1.2) => {
    "msg": "reserve address 192.168.1.2 for network example1"
}
ok: [localhost] => (item=example1/192.168.1.3) => {
    "msg": "reserve address 192.168.1.3 for network example1"
}
ok: [localhost] => (item=example1/192.168.1.4) => {
    "msg": "reserve address 192.168.1.4 for network example1"
}
ok: [localhost] => (item=example1/192.168.1.5) => {
    "msg": "reserve address 192.168.1.5 for network example1"
}
ok: [localhost] => (item=example1/192.168.1.6) => {
    "msg": "reserve address 192.168.1.6 for network example1"
}
ok: [localhost] => (item=example1/192.168.1.7) => {
    "msg": "reserve address 192.168.1.7 for network example1"
}
ok: [localhost] => (item=example1/192.168.1.8) => {
    "msg": "reserve address 192.168.1.8 for network example1"
}
ok: [localhost] => (item=example1/192.168.1.9) => {
    "msg": "reserve address 192.168.1.9 for network example1"
}
ok: [localhost] => (item=example2/192.168.2.1) => {
    "msg": "reserve address 192.168.2.1 for network example2"
}
ok: [localhost] => (item=example2/192.168.2.2) => {
    "msg": "reserve address 192.168.2.2 for network example2"
}
ok: [localhost] => (item=example2/192.168.2.3) => {
    "msg": "reserve address 192.168.2.3 for network example2"
}
ok: [localhost] => (item=example2/192.168.2.4) => {
    "msg": "reserve address 192.168.2.4 for network example2"
}
ok: [localhost] => (item=example2/192.168.2.5) => {
    "msg": "reserve address 192.168.2.5 for network example2"
}
ok: [localhost] => (item=example2/192.168.2.6) => {
    "msg": "reserve address 192.168.2.6 for network example2"
}
ok: [localhost] => (item=example2/192.168.2.7) => {
    "msg": "reserve address 192.168.2.7 for network example2"
}
ok: [localhost] => (item=example2/192.168.2.8) => {
    "msg": "reserve address 192.168.2.8 for network example2"
}
ok: [localhost] => (item=example2/192.168.2.9) => {
    "msg": "reserve address 192.168.2.9 for network example2"
}

PLAY RECAP ************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0