致命:[本地主机]:失败! => {“msg”:“该任务包含一个带有未定义变量的选项。错误是:'dict object'没有属性'json'

问题描述 投票:0回答:1

我的 ansible 剧本中有一个错误:

致命:[localhost]:失败! => {“msg”:“该任务包含一个带有未定义变量的选项。错误是:'dict object'没有属性'json'。'dict object'没有属性'json' 错误似乎位于 '/home/ansibleliza/ansible-router/new/liza/work4.yaml': 第 60 行,第 7 列,但可能 位于文件的其他位置,具体取决于确切的语法问题。 有问题的行似乎是: - 名称:Створити пристрій, якщо він не існує ^ 这里 “}

本质是创建一个 playbook,通过 API 在 netbox 中创建对象。

它是如何工作的:首先,它运行一个Python脚本,该脚本将解析3个配置文件,然后将输出以JSON格式保存在myresult.txt文件中。每次再次运行 playbook 时,都应更新结果文件。要创建的第一个对象是 Site,它将具有同名的 slug 和状态(活动)。接下来,创建一个 Device,它包括之前创建的站点,添加角色 id (id 2 ) 和 device_type (id_1),设备名称取自 myresult.txt,status (active) 。然后创建 VLAN,它们是使用 Vlan Id、名称、状态创建的,所有这些都取自 myresult.txt。接下来,将创建接口,其中包括之前创建的设备、名称、类型、描述、mac、id。如果描述中说该接口已关闭,则不会启用该接口,在描述中将没有描述。另外,有些接口连接到先前创建的 vlan,但有些接口有很多 vlan,有些有 1 个,有些接口根本没有 vlan,或者这些接口被 shutdown(netbox 中的 vlan 在 802.1Q 中标明)。柱子)。还有要点是,在剧本第一次启动期间,所有这些对象都是在网络盒中创建的,并且应该检查该对象是否已经存在(然后它将跳过)或该对象尚不存在并且它将被创建。每次更改配置文件时(例如,如果将新的 VLAN 添加到列表中),则在下次启动 netbox 后,应进行检查,然后在必要时创建新的 VLAN 或其他对象

这是我的剧本:

tasks:
    - name: Run script.py to generate result.txt
      command: python3 "{{ script_path }}"
      register: script_output
      ignore_errors: yes

    - name: Read the content of result.txt
      slurp:
        src: "{{ result_file_path }}"
      register: result_content

    - name: Convert the read data from base64
      set_fact:
        result_data: "{{ result_content['content'] | b64decode | from_json }}"

    - name: Check if the site exists
      uri:
        url: "{{ netbox_url }}/dcim/sites/?name={{ result_data['site'] }}"
        method: GET
        headers:
          Authorization: "Token {{ netbox_token }}"
          Accept: "application/json"
      register: site_check_response

    - name: Create the site if it doesn't exist
      uri:
        url: "{{ netbox_url }}/dcim/sites/"
        method: POST
        body_format: json
        body:
          name: "{{ result_data['site'] }}"
          slug: "{{ result_data['site'] | lower }}"
          status: "active"
        headers:
          Authorization: "Token {{ netbox_token }}"
          Content-Type: "application/json"
        status_code: 201
      when: site_check_response.json.count == 0
      register: site_creation_response

    - name: Check if the device exists
      uri:
        url: "{{ netbox_url }}/dcim/devices/?name={{ result_data['name'] }}"
        method: GET
        headers:
          Authorization: "Token {{ netbox_token }}"
          Accept: "application/json"
      register: device_check_response

    - name: Create the device if it doesn't exist
      uri:
        url: "{{ netbox_url }}/dcim/devices/"
        method: POST
        body_format: json
        body:
          name: "{{ result_data['name'] }}"
          role: 2  # Role ID
          device_type: 1  # Device type ID
          site: "{{ site_creation_response.json.id if site_creation_response is defined else site_check_response.json.results[0].id }}"
          status: "active"
        headers:
          Authorization: "Token {{ netbox_token }}"
          Content-Type: "application/json"
        status_code: 201
      when: device_check_response.json.count == 0

    - name: Check if the VLAN exists
      uri:
        url: "{{ netbox_url }}/ipam/vlans/?site_id={{ (site_creation_response.json.id if (site_creation_response is defined and 'json' in site_creation_response and 'id' in site_creation_response.json) else site_check_response.json.results[0].id if (site_check_response is defined and 'json' in site_check_response and site_check_response.json.results|length > 0) else '') }}&vid={{ item.id }}"
        method: GET
        headers:
          Authorization: "Token {{ netbox_token }}"
          Accept: "application/json"
      loop: "{{ result_data['vlans'] }}"
      register: vlan_check_response
      when: site_creation_response is defined or (site_check_response is defined and site_check_response.json.results|length > 0)

    - name: Create VLANs if they don't exist
      uri:
        url: "{{ netbox_url }}/ipam/vlans/"
        method: POST
        body_format: json
        body:
          name: "{{ item.item.name }}"
          vid: "{{ item.item.id }}"
          site: "{{ site_creation_response.json.id if site_creation_response is defined else site_check_response.json.results[0].id }}"
          status: "active"
        headers:
          Authorization: "Token {{ netbox_token }}"
          Content-Type: "application/json"
        status_code: 201
      loop: "{{ vlan_check_response.results }}"
      when: item.json.count == 0
      loop_control:
        loop_var: item
    - name: Set Default for interfaces_list
      set_fact:
        interfaces_list: []

    - name: Check if the device interfaces exist
      uri:
        url: "{{ netbox_url }}/dcim/interfaces/?device_id={{ device_creation_response.json.id if device_creation_response is defined else device_check_response.json.results[0].id }}&name={{ item.key }}"
        method: GET
        headers:
          Authorization: "Token {{ netbox_token }}"
          Accept: "application/json"
      loop: "{{ result_data['interfaces'] | dict2items }}"
      register: interface_check_response
      when: device_creation_response is defined or (device_check_response is defined and device_check_response.json.results|length > 0)

    - name: Create interfaces if they don't exist
      uri:
        url: "{{ netbox_url }}/dcim/interfaces/"
        method: POST
        body_format: json
        headers:
          Authorization: "Token {{ netbox_token }}"
          Content-Type: "application/json"
        status_code: [201, 400]
        body: >
          {{
            {
              "device": (device_creation_response.json.id if device_creation_response is defined else device_check_response.json.results[0].id),
              "name": item.key,
              "enabled": (false if item.value.description == "shutdown" else true),
              "description": ("No description" if item.value.description == "shutdown" else item.value.description),
              "type": item.value.type,
              "mac_address": (item.value.mac | default('') | replace('.', ''))
            } | to_json
          }}
      loop: "{{ result_data['interfaces'] | dict2items }}"
      loop_control:
        loop_var: item

第一次启动playbook时,会出现我指出的错误,但它可能出现在设备、vlan、接口阶段。有时,当我再次运行时,就没有错误了。我不知道这种行为的原因。

python json ansible netbox
1个回答
0
投票

看起来您的剧本正在尝试使用未定义或未正确传递的变量,特别是应该具有“json”属性的变量。确保您的 python 脚本实际上以 JSON 格式输出到“myresult.txt”。另外,请仔细检查您的剧本是否正确读取“myresult.txt”。如果文件读取部分正常,则问题可能在于您访问数据的方式。确保您尝试访问的数据结构与结果文件中的 JSON 结构匹配。如果没有确切的剧本代码,这些是开始检查的最佳位置!

© www.soinside.com 2019 - 2024. All rights reserved.