【问题标题】:read_csv not happening line by lineread_csv 不是逐行发生的
【发布时间】:2023-02-04 06:22:10
【问题描述】:

我正在尝试读取一个 csv 文件。但是,在打印期间,它不是逐行读取,而是遍历一些内部循环并复制结果。

- name: read csv
  read_csv:
    path: /u00/app/monitor/newrelic_test.csv
    key: Application   
  register: newrelic

- name: Print newrelic var   
  ansible.builtin.debug:
    var: newrelic.list

输出如下所示:

  [testserver1] =>
"newrelic.list": 
        "Application": "Microsoft",
        "env": "Test",
        "Datacenter": "DC1",
        "Hostname": "testserver1",
    },
        "Application": "Apple",
        "env": "Test",
        "Datacenter": "DC2",
        "Hostname": "testserver2",
    }
[testserver2] => {
"newrelic.list": 
    {
        "Application": "Microsoft",
        "env": "Test",
        "Datacenter": "DC1",
        "Hostname": "testserver1",
    },
        "Application": "Apple",
        "env": "Test",
        "Datacenter": "DC2",
        "Hostname": "testserver2",
    }
]

.csv 文件:

Application,env,Datacenter,Hostname
Microsoft,Test,DC1,testserver1
Apple,Test,DC2,testserver2

预期结果应为:

[testserver1] =>
"newrelic.list": 
        "Application": "Microsoft",
        "env": "Test",
        "Datacenter": "DC1",
        "Hostname": "testserver1",
    }
[testserver2] => {
"newrelic.list": 
    {
        "Application": "Apple",
        "env": "Test",
        "Datacenter": "DC2",
        "Hostname": "testserver2",
    }
]

编辑:-下一个块

- name: copy template
  template:
    src: /u00/ansible/Playbooks/files/infra-config.yml_template
    dest: /u00/app/monitor/infra-config.yml
  loop: "{{ newrelic.list }}"
  loop_control:
    loop_var: item

问题:如果未使用newrelic.list,则会出现如下错误:

[testserver1]: FAILED! => {"msg": "Invalid data passed to 'loop', it requires a list, got this instead: {'dict': 

我尝试添加 dict2items 但随后模板无法读取项目。

【问题讨论】:

  • 如果您可以将问题中的 Ansible 输出替换为不包含所有终端格式代码的输出,将会有所帮助。
  • larsks - 我已经删除了来自 Jenkins 的终端格式。

标签: ansible


【解决方案1】:

read_csv 模块不会“逐行”读取 CSV 文件;来自the documentation

读取 [s] 一个 CSV 文件并返回 [s] 一个列表或字典,每行包含一个字典。

所以当你运行这个任务时:

- name: read csv
  read_csv:
    path: data.csv
    key: Application
  register: newrelic

您得到一个变量 newrelic,它有一个空的 list 元素和一个 dict 元素,其中包含来自 CSV 文件的数据,由 Application 键入(因为这就是您要求的)。如果使用 debug 任务查看 newrelic 的值,我们会看到:

ok: [localhost] => {
    "newrelic": {
        "changed": false,
        "dict": {
            "Apple": {
                "Application": "Apple",
                "Datacenter": "DC2",
                "Hostname": "testserver2",
                "env": "Test"
            },
            "Microsoft": {
                "Application": "Microsoft",
                "Datacenter": "DC1",
                "Hostname": "testserver1",
                "env": "Test"
            }
        },
        "failed": false,
        "list": []
    }
}

目前尚不清楚您在这里究竟想做什么,但如果您想通过清单主机名从 CSV 文件中查找值,则需要将其键入 Hostname 而不是:

- name: read csv
  read_csv:
    path: data.csv
    key: Hostname
  register: newrelic

然后你可以写:

- name: Print newrelic var
  ansible.builtin.debug:
    var: newrelic.dict[inventory_hostname]

假设您的清单中有主机 testserver1testserver2,则剧本如下:

- hosts: localhost
  gather_facts: false
  tasks:
    - name: read csv
      read_csv:
        path: data.csv
        key: Hostname
      register: newrelic

- hosts: all
  gather_facts: false
  tasks:
    - name: Print newrelic var
      ansible.builtin.debug:
        var: hostvars.localhost.newrelic.dict[inventory_hostname]

将导致此输出:

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

TASK [read csv] ****************************************************************
ok: [localhost]

PLAY [all] *********************************************************************

TASK [Print newrelic var] ******************************************************
ok: [testserver1] => {
    "hostvars.localhost.newrelic.dict[inventory_hostname]": {
        "Application": "Microsoft",
        "Datacenter": "DC1",
        "Hostname": "testserver1",
        "env": "Test"
    }
}
ok: [testserver2] => {
    "hostvars.localhost.newrelic.dict[inventory_hostname]": {
        "Application": "Apple",
        "Datacenter": "DC2",
        "Hostname": "testserver2",
        "env": "Test"
    }
}

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
testserver1                : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
testserver2                : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

【讨论】:

  • larsks:你是对的,我有下一个块来更新模板并复制到远程服务器。 - 名称:复制模板模板:src:/u00/ansible/Playbooks/files/infra-config.yml_template dest:/u00/app/monitor/infra-config.yml loop:“{{newrelic.list}}”loop_control: loop_var:项目问题是我在 testserver1 和 testserver2 中得到相同的条目而不是上面的读取值。
  • 最好在您的问题中添加其他内容,您可以在其中正确设置格式,而不是将其留在评论中。在您的评论中,您似乎指的是newlist.list,但正如我在此答案中所讨论的那样,newrelic.list 中没有数据。
  • larsks - 编辑了问题并添加了下一个块是什么以及我得到的结果。
  • 当使用key参数给read_csv时,我在newrelic.list中没有得到任何数据;使用 key 参数反而让我得到了一本字典。由于我看到的行为似乎与您不同,因此我不确定我能否提供超出此答案中所示内容的帮助。
  • larsks - 感谢您的支持。直到从 csv 读取和调试,它按预期工作。但是当我将这些数据推送到模板时,这就出错了。要么我在两台服务器上都得到相同的项目,要么我收到找不到模板属性的错误。
猜你喜欢
  • 1970-01-01
  • 2018-08-18
  • 2020-08-12
  • 1970-01-01
  • 2013-12-17
  • 2018-12-07
  • 1970-01-01
  • 2019-12-16
  • 1970-01-01
相关资源
最近更新 更多