1

在我开始之前,我应该声明我对 YAML 和 JSON 都是新手,所以格式化规则并不那么清楚。

我正在尝试编写一个 Perl 脚本(Perl,因为我知道它存在于我们所有的服务器上。)它将为各种主机更新几个与网络相关的设置。我的偏好是将所有设置放在一个文件中,并根据脚本运行的主机更新配置。

我查看了 YAML,但由于我不能做类似的事情,我有点害怕:

host:
  hostname: first
    interface: eth0
      oldip: 1.2.3.4
      newip: 2.3.4.5
      oldgw: 1.2.3.1
      newgw: 2.3.4.1
    interface: eth1
      oldip: 1.2.3.4
      newip: 2.3.4.5
      oldgw: 1.2.3.1
      newgw: 2.3.4.1

host:
  hostname: second
    interface: eth0
      oldip: 1.2.3.4
      newip: 2.3.4.5
      oldgw: 1.2.3.1
      newgw: 2.3.4.1
    interface: eth1
      oldip: 1.2.3.4
      newip: 2.3.4.5
      oldgw: 1.2.3.1
      newgw: 2.3.4.1

也就是说,我已经将它插入到 YAML 验证器中并且它失败了。

我发现,对于 YAML,我可以执行以下操作:

host: "first"
interface1:
  name: eth0
  oldip: 1.2.3.4
  newip: 2.3.4.5
  oldgw: 1.2.3.1
  newgw: 2.3.4.1
interface2:
  name: eth1
  oldip: 1.2.3.4
  newip: 2.3.4.5
  oldgw: 1.2.3.1
  newgw: 2.3.4.1

但是,这不太理想,因为它使得在一个文件中拥有多个主机是不可能的。我基于这样一个事实,即我在尝试此操作时不断从我使用的在线验证器中收到错误。

我看过使用 JSON,但我也不知道所有的规则。我知道以下方法不起作用:

{
    "host": "first",
    "interface1": {
        "newip": "2.3.4.5",
        "oldip": "1.2.3.4",
        "oldgw": "1.2.3.1",
        "name": "eth0",
        "newgw": "2.3.4.1"
    },
    "interface2": {
        "newip": "2.3.4.5",
        "oldip": "1.2.3.4",
        "oldgw": "1.2.3.1",
        "name": "eth1",
        "newgw": "2.3.4.1"
    }
}

{
    "host": "second",
    "interface1": {
        "newip": "2.3.4.5",
        "oldip": "1.2.3.4",
        "oldgw": "1.2.3.1",
        "name": "eth0",
        "newgw": "2.3.4.1"
    },
    "interface2": {
        "newip": "2.3.4.5",
        "oldip": "1.2.3.4",
        "oldgw": "1.2.3.1",
        "name": "eth1",
        "newgw": "2.3.4.1"
    }
}

有没有一种可以让我将所有主机及其信息存储在一个可以解析的文件中的格式?

如果 YAML 或 JSON 都适合,我做错了什么?

4

4 回答 4

3

您的 YAML 问题与host最初的问题相同interface:您试图将子键与包含它们的键放在同一级别。

host:
  name: first
  interface1:
    name: eth0
    oldip: 1.2.3.4
    newip: 2.3.4.5
    oldgw: 1.2.3.1
    newgw: 2.3.4.1
  interface2:
    name: eth1
    oldip: 1.2.3.4
    newip: 2.3.4.5
    oldgw: 1.2.3.1
    newgw: 2.3.4.1

应该可以工作,尽管这仍然不能满足您对多个主机的需求。为此(并更好地处理多个接口),您应该使用列表:

host:
  - name: first_host
    interface:
      - name: eth0
        oldip: 1.2.3.4
        newip: 2.3.4.5
        oldgw: 1.2.3.1
        newgw: 2.3.4.1
      - name: eth1
        oldip: 1.2.3.4
        newip: 2.3.4.5
        oldgw: 1.2.3.1
        newgw: 2.3.4.1
  - name: second_host
    interface:
    - ...

当 Perl 读入时,这将为您提供以下结构:

{
  "host": [
    {
      "interface": [
        {
          "newip": "2.3.4.5", 
          "oldip": "1.2.3.4", 
          "oldgw": "1.2.3.1", 
          "name": "eth0", 
          "newgw": "2.3.4.1"
        }, 
        {
          "newip": "2.3.4.5", 
          "oldip": "1.2.3.4", 
          "oldgw": "1.2.3.1", 
          "name": "eth1", 
          "newgw": "2.3.4.1"
        }
      ], 
      "name": "first_host"
    }
  ]
}

就 JSON 而言,这是 YAML 的一个子集。就个人而言,我更喜欢使用完整的 YAML 规范,但 JSON 提供了与非 Perl 语言的更多互操作性。

于 2013-08-18T17:22:14.747 回答
1

我更喜欢 JSON 而不是 YAML。我最近构建了一个系统,其“用户界面”(ha)基本上是一个巨大的配置文件;用户需要编辑该配置文件来控制系统;我对那个文件使用了 YAML。事实证明,YAML 有一些非常烦人的陷阱,使其不适合人类——例如,它对空格非常挑剔。

此外,它一般不太熟悉:我猜任何有编程经验的人都会遇到 JSON 并理解它。但 YAML 更小众。

如果您不使用 YAML 的高级功能(例如定义变量然后稍后引用它们的能力),我建议您改用 JSON。

于 2013-08-18T17:30:50.080 回答
0

不关心格式。填充数据结构并让JSONYAML为您完成繁琐的工作。如果您要自己生成和解析文件,那么使用 JSON 或 YAML 几乎没有任何优势。

于 2013-08-18T16:41:23.263 回答
0

The exact format is unimportant: both YAML and JSON are fine. Actually, I would recommend to keep this specific part pluggable.

The issue with your YAML is that the data structure has to make some sense, e.g.:

- host:
    hostname: first
    interfaces:
      eth0:
        oldip: 1.2.3.4
        newip: 2.3.4.5
        oldgw: 1.2.3.1
        newgw: 2.3.4.1
      eth1:
        oldip: 1.2.3.4
        newip: 2.3.4.5
        oldgw: 1.2.3.1
        newgw: 2.3.4.1
- host:
    hostname: second
    interfaces:
      ...

Or if the interfaces have to be ordered:

- host:
    hostname: first
    interfaces:
      -
        name: eth0
        oldip: 1.2.3.4
        newip: 2.3.4.5
        oldgw: 1.2.3.1
        newgw: 2.3.4.1
      -
        name: eth1
        oldip: 1.2.3.4
        newip: 2.3.4.5
        oldgw: 1.2.3.1
        newgw: 2.3.4.1

If writing YAML manually is to tedious for you, just write a small script that generates it for you.

Note that lists have to be somehow introduces by a marker like -. Intendation is not sufficient for this.

于 2013-08-18T17:25:32.443 回答