我是Ansible的新手,目前正在努力编写一本剧本,以使用以下模块来部署某些Palo Alto配置:
https://github.com/PaloAltoNetworks/ansible-pan
我已经花了一个星期的时间试图解决这个问题,但我无法弄清楚为什么这个“列表”不起作用。总之,此代码连接到防火墙,创建一个新的地址对象,并且如果存在“ http”或“ https”的“服务”变量,则它将将该对象添加到现有的防火墙地址组中。
问题在于防火墙组的添加。完成此任务的任务似乎是覆盖组中的现有对象,而不是附加到该对象。
要尝试解决这个问题,我有一个任务是“查找”现有对象(结果在字典中,然后我找到一个列表变量。然后在“ static_value”作业中使用此变量和新的服务器变量来:更新地址组。这似乎不起作用,并且看起来超出了字符限制,就好像它是一个字符串一样。
我还尝试过自己重新添加现有对象,并且以下操作也失败了:
"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"
}
有一次我可以使它工作的方法是在“如果将80/443的EFW对象添加到地址组”任务中使用“ with_items”循环来填充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"
答案 0 :(得分:0)
免责声明,这是一个完全盲目的调试,因为我无法复制您原始帖子中的任何内容。如果可能,请始终考虑制作minimal reproducible examples。
inline documentation of your module for the static_value
parameter明确声明它正在等待“地址对象”列表:
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