首页 > 解决方案 > 在 Groovy 中循环文件以创建 JSON 模板

问题描述

我正在尝试为 Openshift 中的服务构建 JSON 模板。我需要设置一个 groovy 脚本,该脚本将遍历包含多个端口的文本文件,以便创建 JSON 模板的端口部分。

这是包含端口的文件的样子。

cat ports.txt
  9000
  8090
  7010
  6012

这是我创建模板的常规脚本。该脚本包含端口 9000 的硬编码文本。

def builder = new groovy.json.JsonBuilder()
builder.apiVersion {
  apiVersion 'v1'
  kind 'Service'
  metadata {
    name 'apache'
    labels {
     app "apache"
     name "apache"
 }
}
spec {
selector {
  app 'apache'
 }
  ports {
  name "9000-tcp"
  protocol "TCP"
  port "9000"
  targetPort "9000"
  }
}
}
println builder.toPrettyString()

运行脚本会显示以下内容:

{
"apiVersion": {
    "apiVersion": "v1",
    "kind": "Service",
    "metadata": {
        "name": "apache",
        "labels": {
            "app": "apache",
            "name": "apache"
        }
    },
    "spec": {
        "selector": {
            "app": "apache"
        },
        "ports": {
            "name": "80-tcp",
            "protocol": "TCP",
            "port": "8081"
        }
    }
}

}

我希望最终产品看起来像这样

{
    "apiVersion": "v1",
    "kind": "Service",
    "metadata": {
        "name": "apache",
        "labels": {
            "app": "apache",
            "name": "apache"
        }
    },
    "spec": {
        "selector": {
            "app": "apache"
        },
        "ports": {
            "name": "80-tcp",
            "protocol": "TCP",
            "port": "8081"
        }
        "ports": {
            "name": "8090-tcp",
            "protocol": "TCP",
            "port": "8090",
            "targetPort": "8090"
        }
        "ports": {
            "name": "7010-tcp",
            "protocol": "TCP",
            "port": "7010",
            "targetPort": "7010"
        }
        "ports": {
            "name": "6012-tcp",
            "protocol": "TCP",
            "port": "6012",
            "targetPort": "6012"
        }
    }
}
}

如何在此模板中嵌入循环以添加创建与文件中一样多的端口file.txt

标签: jsongroovy

解决方案


您建议的输出不是有效的 JSON...您不能ports在显示的同一级别上拥有多个对象...但是您可以制作ports如下对象列表:

def builder = new groovy.json.JsonBuilder()
builder {
    apiVersion 'v1'
    kind 'Service'
    metadata {
        name 'apache'
        labels {
            app "apache"
            name "apache"
        }
    }
    spec {
        selector {
            app 'apache'
        }
        ports new File('ports.txt').readLines()*.trim().collect { p ->
            [name: "$p-tcp", protocol: "TCP", port: "$p", targetPort: "$p"]
        }
    }
}

println builder.toPrettyString()

输出是:

    {
        "apiVersion": "v1",
        "kind": "Service",
        "metadata": {
            "name": "apache",
            "labels": {
                "app": "apache",
                "name": "apache"
            }
        },
        "spec": {
            "selector": {
                "app": "apache"
            },
            "ports": [
                {
                    "name": "9000-tcp",
                    "protocol": "TCP",
                    "port": "9000",
                    "targetPort": "9000"
                },
                {
                    "name": "8090-tcp",
                    "protocol": "TCP",
                    "port": "8090",
                    "targetPort": "8090"
                },
                {
                    "name": "7010-tcp",
                    "protocol": "TCP",
                    "port": "7010",
                    "targetPort": "7010"
                },
                {
                    "name": "6012-tcp",
                    "protocol": "TCP",
                    "port": "6012",
                    "targetPort": "6012"
                }
            ]
        }
    }

推荐阅读