Closed hongkailiu closed 5 years ago
Per the error message, std.manifestYamlStream
requires an array as input:
stream mode: top-level object was a object, should be an array whose elements hold the JSON for each document in the stream.
Can you show us the outermost layer of your _prowprometheusrule.jsonnet file?
I see; it's a top-level JSON object. If you wrap that object in an array, this should work for you.
local alerts = (import 'prometheus.libsonnet').prometheusAlerts;
[
{
// ...
},
]
That will get you a stream of YAML documents. In your case, you'll wind up with just one document.
May I ask why it requires an array?
Tried with wrapping it into array, but the output is not yaml
$ bazel build //prow/cluster/monitoring/mixins/prometheus:prow_prometheusrule
DEBUG: /home/hongkliu/.cache/bazel/_bazel_hongkliu/ef5e8e918e6947b01dd429bce37b0e43/external/bazel_toolchains/rules/rbe_repo/checked_in.bzl:256:5: rbe_default is using checked-in configs 'struct(config_repos = [], create_cc_configs = True, create_java_configs = True, env = {"ABI_LIBC_VERSION": "glibc_2.19", "ABI_VERSION": "clang", "BAZEL_COMPILER": "clang", "BAZEL_HOST_SYSTEM": "i686-unknown-linux-gnu", "BAZEL_TARGET_CPU": "k8", "BAZEL_TARGET_LIBC": "glibc_2.19", "BAZEL_TARGET_SYSTEM": "x86_64-unknown-linux-gnu", "CC": "clang", "CC_TOOLCHAIN_NAME": "linux_gnu_x86"}, java_home = "/usr/lib/jvm/java-8-openjdk-amd64", name = "9.0.0")'
INFO: Analyzed target //prow/cluster/monitoring/mixins/prometheus:prow_prometheusrule (29 packages loaded, 230 targets configured).
INFO: Found 1 target...
Target //prow/cluster/monitoring/mixins/prometheus:prow_prometheusrule up-to-date:
bazel-bin/prow/cluster/monitoring/mixins/prometheus/prow_prometheusrule.yaml
INFO: Elapsed time: 28.199s, Critical Path: 26.65s
INFO: 15 processes: 15 linux-sandbox.
INFO: Build completed successfully, 19 total actions
$ cat bazel-bin/prow/cluster/monitoring/mixins/prometheus/prow_prometheusrule.yaml
---
{
"apiVersion": "monitoring.coreos.com/v1",
"kind": "PrometheusRule",
"metadata": {
"labels": {
"prometheus": "prow",
"role": "alert-rules"
},
"name": "prometheus-prow-rules",
"namespace": "prow-monitoring"
},
"spec": {
"groups": [
{
"name": "ci-absent",
"rules": [
{
"alert": "deckDown",
"annotations": {
"message": "The service deck has been down for 5 minutes."
},
"expr": "absent(up{job=\"deck\"} == 1)\n",
"for": "5m",
"labels": {
"severity": "slack"
}
},
{
"alert": "ghproxyDown",
"annotations": {
"message": "The service ghproxy has been down for 5 minutes."
},
"expr": "absent(up{job=\"ghproxy\"} == 1)\n",
"for": "5m",
"labels": {
"severity": "slack"
}
},
{
"alert": "hookDown",
"annotations": {
"message": "The service hook has been down for 5 minutes."
},
"expr": "absent(up{job=\"hook\"} == 1)\n",
"for": "5m",
"labels": {
"severity": "slack"
}
},
{
"alert": "plankDown",
"annotations": {
"message": "The service plank has been down for 5 minutes."
},
"expr": "absent(up{job=\"plank\"} == 1)\n",
"for": "5m",
"labels": {
"severity": "slack"
}
},
{
"alert": "sinkerDown",
"annotations": {
"message": "The service sinker has been down for 5 minutes."
},
"expr": "absent(up{job=\"sinker\"} == 1)\n",
"for": "5m",
"labels": {
"severity": "slack"
}
},
{
"alert": "tideDown",
"annotations": {
"message": "The service tide has been down for 5 minutes."
},
"expr": "absent(up{job=\"tide\"} == 1)\n",
"for": "5m",
"labels": {
"severity": "slack"
}
}
]
},
{
"name": "prow-monitoring-absent",
"rules": [
{
"alert": "ServiceLostHA",
"annotations": {
"message": "The service {{ $labels.job }} has at most 1 instance for 5 minutes."
},
"expr": "sum(up{job=~\"grafana|prometheus|alertmanager\"}) by (job) <= 1\n",
"for": "5m",
"labels": {
"severity": "slack"
}
},
{
"alert": "alertmanagerDown",
"annotations": {
"message": "The service alertmanager has been down for 5 minutes."
},
"expr": "absent(up{job=\"alertmanager\"} == 1)\n",
"for": "5m",
"labels": {
"severity": "slack"
}
},
{
"alert": "prometheusDown",
"annotations": {
"message": "The service prometheus has been down for 5 minutes."
},
"expr": "absent(up{job=\"prometheus\"} == 1)\n",
"for": "5m",
"labels": {
"severity": "slack"
}
}
]
}
]
}
}
...
It requires an array because it's anticipating emitting a stream of several documents. You could implement it to accept a single object, and if that object is an array, do what it does normally, and if not, emit a stream of the single object. It's just not implemented that way today.
As for why you wound up with a YAML stream in which the content is still JSON, I'm confused too. @sparkprime, have you seen this before?
json is a subset of yaml and I am pretty sure that is just how jsonnet behaves currently. @hongkailiu can this be closed?
Now I see what you mean by json is a subset of yaml: json can be parsed by any yaml parser https://jsonnet.org/learning/getting_started.html#stream
yaml_stream = True
does the right thing according to above doc, just not what I wanted though.
Closing the issue.
@Globegitter Any known bazel tool which in be used to convert json to (real) yaml?
@hongkailiu nope, but it should be fairly easy to write one. Here for example I have written a json to js converter: https://github.com/ecosia/bazel_rules_nodejs_contrib/tree/master/internal/json_to_js
But also may I ask why you need "real" yaml? Is the output file meant to be read by people?
But also may I ask why you need "real" yaml? Is the output file meant to be read by people?
https://github.com/kubernetes/test-infra/pull/14197#issuecomment-528156238
Originally when I opened the issue, I wanted yaml format for debugging as the output is used as input for rule k8s_object
. Debugging (when things do not work) with yaml is easier. Now, the whole jsonnet -> json -> k8s
pipeline works nicely together. The yaml format is not essential (only nice-to-have).
I also found a workaround with genrule
to convert json to yaml (the links above) with https://github.com/brancz/gojsontoyaml
What did I miss? Thanks.