Как использовать переменную «список» в этой задаче

Я новичок в Ansible и в настоящее время работаю над составлением сценария для развертывания некоторой конфигурации Palo Alto с использованием следующих модулей:

https://github.com/PaloAltoNetworks/ansible-пан

Я занимаюсь этим уже неделю, пытаясь разобраться, и я не могу понять, почему этот «список» не работает. Таким образом, этот код подключается к брандмауэру, создает новый адресный объект, и если существует переменная «служба», которая говорит http или https, то он добавит этот объект в существующую адресную группу брандмауэра.

Проблема с добавлением в группу брандмауэра. Задача, которая выполняет это, кажется, перезаписывает существующие объекты в группе, а не добавляет к ней.

Чтобы попытаться бороться с этим, у меня есть задача, которая «находит» существующие объекты (результаты находятся в словаре, который я затем переношу в переменную списка. Эта переменная + новая серверная переменная затем используются в задании «static_value» для обновления адреса group. Это не работает и похоже, что превышен лимит символов, как если бы это была одна строка.

Я также попытался повторно добавить существующие объекты самостоятельно, и это также не удалось со следующим:

"msg": "Failed apply:  DevUKST-Web-Servers -> static '['UKST1MXWEB002D-NAT-EFW-01', 'UKST1MXWEB003D-NAT-EFW-01']' is not a valid reference\n DevUKST-Web-Servers -> static is invalid"
}

Единственный раз, когда я могу заставить его работать, — это использовать цикл with_items в задаче «Добавить объекты EFW в адресную группу, если 80/443» для заполнения static_values. Он перебирает «результат» задачи поиска объектов и добавляет новый адресный объект «efwone» в конце. Проблема с этим заключается в том, что он перезаписывает каждый результат каждый раз, когда он зацикливается.

Это пьеса, которую я запускаю

---

 - hosts: localhost
   connection: local
   gather_facts: false

   roles:
    - role: PaloAltoNetworks.paloaltonetworks

  vars_prompt:
    - name: "username"
      prompt: "Enter Username"
    - name: "password"
      prompt: "Enter Password"

  vars:
     cli:
         ip_address: x.x.x.x
         username: "{{ username }}"
         password: "{{ password }}"
         port: 443  

     objects: []
     efwone: "{{ hostname }}-NAT-EFW-01"

  tasks: 
    - name: include variables (free-form)
      tags: [dev, prod]
      include_vars: vars.yml   
      no_log: 'false'

 # Configure Address Objects

    - name: Create object "NAT-EFW-01"
      tags: [dev, prod]
      panos_address_object:
         provider: "{{ cli }}"
         name: "{{ hostname }}-NAT-EFW-01"
         value: "{{ efw01_serviceip }}"
         description: "{{ service_name }} - Public LB Backend pool IP"
         commit: false

    - name: Create object "Server Object"
      tags: [dev, prod]
      panos_address_object:
          provider: "{{ cli }}"
          name: "{{ hostname }}"
          value: "{{ serverip }}"
          description: "{{ service_name }} - {{ service_type }}"
          commit: false

 # Find existing objects in webserver address group

    - name: Find objects in address group
      tags: dev
      when: service == "http" or service == "https"
      panos_object_facts:
       provider: "{{ cli }}"
       name: "{{ dgshort }}-Web-Servers"
       object_type: "address-group"
      register: output

    - name: Display Output
      tags: [dev, prod]
      debug: msg = "{{ output.results.static_value }}"

    - name: Display efwone
      tags: [dev, prod]
      debug: var=efwone


    - name: Populate list with address objects
      tags: [dev, prod]
      set_fact: 
         objects: "{{ output.results.static_value + [ efwone ] }}"

    - name: Display new object list
      tags: [dev, prod]
      debug: var=objects

# Add EFW objects to address group if 80/443

    - name: Update Web-Servers group dev
      tags: dev
      when: service == "http" or service == "https"
      panos_address_group:
       provider: "{{ cli }}"
       name: "{{ dgshort }}-Web-Servers"
       static_value: [ "{{ objects }}" ]
       commit: false

Module:

#  Copyright 2018 Palo Alto Networks, Inc
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

from __future__ import absolute_import, division, print_function
__metaclass__ = type

ANSIBLE_METADATA = {'metadata_version': '1.1',
                    'status': ['preview'],
                    'supported_by': 'community'}

DOCUMENTATION = '''
---
module: panos_address_group
short_description: Create address group objects on PAN-OS devices.
description:
    - Create address group objects on PAN-OS devices.
author:
    - Michael Richardson (@mrichardson03)
    - Garfield Lee Freeman (@shinmog)
version_added: "2.8"
requirements:
    - pan-python can be obtained from PyPI U(https://pypi.python.org/pypi/pan-python)
    - pandevice can be obtained from PyPI U(https://pypi.python.org/pypi/pandevice)
notes:
    - Panorama is supported.
    - Check mode is supported.
extends_documentation_fragment:
    - panos.transitional_provider
    - panos.vsys
    - panos.device_group
    - panos.state
options:
    name:
        description:
            - Name of address group to create.
        required: true
    static_value:
        description:
            - List of address objects to be included in the group.
        type: list
    dynamic_value:
        description:
            - Registered IP tags for a dynamic address group.
        type: string
    description:
        description:
            - Descriptive name for this address group.
    tag:
        description:
            - List of tags to add to this address group.
        type: list
    commit:
        description:
            - Commit changes after creating object.  If I(ip_address) is a Panorama device, and I(device_group) is
              also set, perform a commit to Panorama and a commit-all to the device group.
        default: true
        type: bool
'''

EXAMPLES = '''
- name: Create object group 'Prod'
  panos_address_group:
    provider: '{{ provider }}'
    name: 'Prod'
    static_value: ['Test-One', 'Test-Three']
    tag: ['Prod']
- name: Create object group 'SI'
  panos_address_group:
    provider: '{{ provider }}'
    name: 'SI'
    dynamic_value: "'SI_Instances'"
    tag: ['SI']
- name: Delete object group 'SI'
  panos_address_group:
    provider: '{{ provider }}'
    name: 'SI'
    state: 'absent'
'''

RETURN = '''
# Default return values
'''

from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.panos.panos import get_connection


try:
    from pandevice.objects import AddressGroup
    from pandevice.errors import PanDeviceError
except ImportError:
    pass


def main():
    helper = get_connection(
        vsys=True,
        device_group=True,
        with_classic_provider_spec=True,
        with_state=True,
        required_one_of=[
            ['static_value', 'dynamic_value'],
        ],
        argument_spec=dict(
            name=dict(type='str', required=True),
            static_value=dict(type='list'),
            dynamic_value=dict(),
            description=dict(),
            tag=dict(type='list'),
            commit=dict(type='bool', default=True),
        ),
    )
    mutually_exclusive = [
        ['static_value', 'dynamic_value']
    ]

    module = AnsibleModule(
        argument_spec=helper.argument_spec,
        required_one_of=helper.required_one_of,
        mutually_exclusive=mutually_exclusive,
        supports_check_mode=True,
    )

    # Verify libs are present, get parent object.
    parent = helper.get_pandevice_parent(module)

    # Object params.
    spec = {
        'name': module.params['name'],
        'static_value': module.params['static_value'],
        'dynamic_value': module.params['dynamic_value'],
        'description': module.params['description'],
        'tag': module.params['tag'],
    }

    # Other info.
    commit = module.params['commit']

    # Retrieve current info.
    try:
        listing = AddressGroup.refreshall(parent, add=False)
    except PanDeviceError as e:
        module.fail_json(msg='Failed refresh: {0}'.format(e))

    # Build the object based on the user spec.
    obj = AddressGroup(**spec)
    parent.add(obj)

    # Apply the state.
    changed = helper.apply_state(obj, listing, module)

    # Commit.
    if commit and changed:
        helper.commit(module)

    # Done.
    module.exit_json(changed=changed)


if __name__ == '__main__':
    main()

Это результаты

ok: [localhost] => {
    "changed": false, 
    "invocation": {
        "module_args": {
            "api_key": null, 
            "device_group": "shared", 
            "ip_address": null, 
            "name": "DevUKST-Web-Servers", 
            "name_regex": null, 
            "object_type": "address-group", 
            "password": null, 
            "port": 443, 
            "provider": {
                "api_key": null, 
                "ip_address": "x.x.x.x", 
                "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", 
                "port": 443, 
                "serial_number": null, 
                "username": "xxxx"
            }, 
            "username": "admin", 
            "vsys": "vsys1"
        }
    }, 
    "objects": [
        {
            "description": null, 
            "dynamic_value": null, 
            "name": "DevUKST-Web-Servers", 
            "static_value": [
                "UKST1MXWEB002D-NAT-EFW-01", 
                "UKST1MXWEB003D-NAT-EFW-01"
            ], 
            "tag": null
        }
    ], 
    "results": {
        "description": null, 
        "dynamic_value": null, 
        "name": "DevUKST-Web-Servers", 
        "static_value": [
            "UKST1MXWEB002D-NAT-EFW-01", 
            "UKST1MXWEB003D-NAT-EFW-01"
        ], 
        "tag": null
    }
}

TASK [Display Output] **********************************************************************************************************************************************************
task path: /etc/ansible/playbooks/NETOPS/AZURE/PALO/deployserviceparams.yml:91
ok: [localhost] => {
    "msg": [
        "UKST1MXWEB002D-NAT-EFW-01", 
        "UKST1MXWEB003D-NAT-EFW-01"
    ]
}

TASK [Display efwone] **********************************************************************************************************************************************************
task path: /etc/ansible/playbooks/NETOPS/AZURE/PALO/deployserviceparams.yml:95
ok: [localhost] => {
    "efwone": "Test-NAT-EFW-01"
}

TASK [Populate list with address objects] **************************************************************************************************************************************
task path: /etc/ansible/playbooks/NETOPS/AZURE/PALO/deployserviceparams.yml:100
ok: [localhost] => {
    "ansible_facts": {
        "objects": [
            "UKST1MXWEB002D-NAT-EFW-01", 
            "UKST1MXWEB003D-NAT-EFW-01", 
            "Test-NAT-EFW-01"
        ]
    }, 
    "changed": false
}

TASK [Display new object list] *************************************************************************************************************************************************
task path: /etc/ansible/playbooks/NETOPS/AZURE/PALO/deployserviceparams.yml:105
ok: [localhost] => {
    "objects": [
        "UKST1MXWEB002D-NAT-EFW-01", 
        "UKST1MXWEB003D-NAT-EFW-01", 
        "Test-NAT-EFW-01"
    ]
}

fatal: [localhost]: FAILED! => {
    "changed": false, 
    "invocation": {
        "module_args": {
            "api_key": null, 
            "commit": false, 
            "description": null, 
            "device_group": "shared", 
            "dynamic_value": null, 
            "ip_address": null, 
            "name": "DevUKST-Web-Servers", 
            "password": null, 
            "port": 443, 
            "provider": {
                "api_key": null, 
                "ip_address": "x.x.x.x", 
                "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", 
                "port": 443, 
                "serial_number": null, 
                "username": "xxxxx"
            }, 
            "state": "present", 
            "static_value": [
                [
                    "UKST1MXWEB002D-NAT-EFW-01", 
                    "UKST1MXWEB003D-NAT-EFW-01", 
                    "Test-NAT-EFW-01"
                ]
            ], 
            "tag": null, 
            "username": "admin", 
            "vsys": "vsys1"
        }
    }, 
    "msg": "Failed apply:  DevUKST-Web-Servers -> static Node can be at most 63 characters, but current length: 77 value: ['UKST1MXWEB002D-NAT-EFW-01', 'UKST1MXWEB003D-NAT-EFW-01', 'Test-NAT-EFW-01']...\n DevUKST-Web-Servers -> static is invalid"

Введение в Ansible Roles
Введение в Ansible Roles
Ansible - это отличный инструмент управления конфигурацией, который можно использовать для автоматизации настройки или развертывания на большом...
1
0
457
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Отказ от ответственности Это полностью слепая отладка, так как я не могу ничего воспроизвести из вашего исходного сообщения. Всегда рассматривайте вариант минимальные воспроизводимые примеры, если это возможно.


встроенная документация вашего модуля для параметра static_value четко указывает, что ожидает список «адресных объектов»:

static_value:
    description:
        - List of address objects to be included in the group.
    type: list

Примечание: Из остальной части вашего поста я слепо предполагаю, что строка является допустимым адресным объектом.

В выводе вашего запуска мы видим, что вы отправляете не список адресных объектов но список списков адресных объектов

    "static_value": [
                [
                    "UKST1MXWEB002D-NAT-EFW-01", 
                    "UKST1MXWEB003D-NAT-EFW-01", 
                    "Test-NAT-EFW-01"
                ]
            ]

Проблемная строка вашей пьесы, которая приводит к этой ситуации, находится в вашей последней задаче:

static_value: [ "{{ objects }}" ]

Ваша последняя задача должна быть (обратите внимание на исчезнувшие скобки)

    - name: Update Web-Servers group dev
      tags: dev
      when: service == "http" or service == "https"
      panos_address_group:
        provider: "{{ cli }}"
        name: "{{ dgshort }}-Web-Servers"
        static_value: "{{ objects }}"
        commit: false

Не могу поверить, как это было просто! Спасибо большое. Я даже не заметил, что это был список в списке, пока вы не указали на это. Глядя на результаты сейчас, это на самом деле совершенно очевидно с двумя наборами [].

Drusstheledg3 16.07.2019 09:32

Если это решит вашу проблему, вы должны принять ответ, чтобы другие знали, что существует фактическое решение.

Zeitounator 16.07.2019 14:01

Другие вопросы по теме