我正在尝试使用 jq 提取 kubeconfig 数据。
kubectl config view --raw -o json | jq ...
有一个这样的json:
{
"kind": "Config",
"apiVersion": "v1",
"preferences": {},
"clusters": [
{
"name": "some-name",
"cluster": {
"server": "https://some-url",
"certificate-authority-data": "some-cert"
}
},
{
"name": "another-name",
"cluster": {
"server": "https://another-url",
"certificate-authority-data": "another-cert"
}
}
],
"users": [
{
"name": "some-name",
"user": {
"username": "some-user",
"password": "some-password"
}
},
{
"name": "another-name",
"user": {
"username": "another-user",
"password": "another-password"
}
}
],
"contexts": [],
"current-context": "some-context"
}
Run Code Online (Sandbox Code Playgroud)
问题 1: 对于给定的名称,“some-name”,我想提取 json:
{
url: "https://some-url",
cert: "some-cert",
username: "some-user",
password: "some-password"
}
Run Code Online (Sandbox Code Playgroud)
问题#2: “用户”子部分可以有其他格式
"users": [
{
"name": "...",
"user": {
"exec": {
...
}
Run Code Online (Sandbox Code Playgroud)
哪里.user.username
或.user.password
两者都可能丢失
在这种情况下,整体查询应返回“{}”,即使“集群”查询/分支有结果
问题 3,作为 Jeff Mercado 回答的后续:
我想获得所有集群,加入(分组)名称:
查看手册,https://stedolan.github.io/jq/manual/#Builtinoperatorsandfunctions,
“乘法、除法、取模:*、/ 和 %”部分,例如:
jq '{"k": {"a": 1, "b": 2}} * {"k": {"a": 0,"c": 3}}' => {"k": {"a": 0, "b": 2, "c": 3}}'
Run Code Online (Sandbox Code Playgroud)
假设“k”是“name”的值,给出大概正确的结果。因此,按“k”分组,合并(*)结果。
我产生了以下查询:
echo "${json}" | jq -r '(.clusters[] | {(.name): {url: .cluster.server, cert: .cluster["certificate-authority-data"]}}) * (.users[] | {(.name): {user: .user.username, password: .user.password}})'
Run Code Online (Sandbox Code Playgroud)
第一部分返回 {"name": {url: cert}},第二部分是 {"name": {username, password}} 但是,结果不是像 jq 手册中那样合并,而是其他东西......产品?
{
"some-name": {
"url": "https://some-url",
"cert": "some-cert",
"user": "some-user",
"password": "some-password"
}
}
{
"another-name": {
"url": "https://another-url",
"cert": "another-cert"
},
"some-name": {
"user": "some-user",
"password": "some-password"
}
}
{
"some-name": {
"url": "https://some-url",
"cert": "some-cert"
},
"another-name": {
"user": "another-user",
"password": "another-password"
}
}
{
"another-name": {
"url": "https://another-url",
"cert": "another-cert",
"user": "another-user",
"password": "another-password"
}
}
Run Code Online (Sandbox Code Playgroud)
为什么/是什么?有点像我(很可能是错误地)理解的产品('*')而不是 jq 教程的想法
实验: 我现在有 2 个查询产生部分结果。
让我们获取原始 json(上图)并解析:
read -d '' json << EOF
...
EOF
Run Code Online (Sandbox Code Playgroud)
查询:
echo "${json}" | jq -r '.clusters[] | select(.name=="some-name") | .cluster | {url: .server, cert: .["certificate-authority-data"]}' &&\
echo "${json}" | jq -r '.users[] | select(.name=="some-name") | .user | {user: .username, password: .password}'
Run Code Online (Sandbox Code Playgroud)
将产生拆分输出:
{
"url": "https://some-url",
"cert": "some-cert"
}
{
"user": "some-user",
"password": "some-password"
}
Run Code Online (Sandbox Code Playgroud)
或者,添加密钥以进行进一步合并:
echo "${json}" | jq -r '.clusters[] | select(.name=="some-name") | {name: .name, url: .cluster.server, cert: .cluster["certificate-authority-data"]}' &&\
echo "${json}" | jq -r '.users[] | select(.name=="some-name") | {name: .name, user: .user.username, password: .user.password}'
Run Code Online (Sandbox Code Playgroud)
将产生:
{
"name": "some-name",
"url": "https://some-url",
"cert": "some-cert"
}
{
"name": "some-name",
"user": "some-user",
"password": "some-password"
}
Run Code Online (Sandbox Code Playgroud)
"name" 不是必需的,但可以用作连接操作
因此,您已经知道如何分别按名称获取集群和用户,第一步是在单个过滤器中同时选择它们:
(.clusters[] | select(.name == $name).cluster), (.users[] | select(.name == $name).user)
Run Code Online (Sandbox Code Playgroud)
这将产生两个独立的对象,集群,然后是用户。但我们想合并它们。有很多方法可以做到这一点。您可以+
直接添加它们 ( ) 或合并它们 ( *
) 但没有真正的区别。您只需要在需要的地方将属性重新映射到您想要的名称。
(.clusters[] | select(.name == $name).cluster | {url: .server, cert: ."certificate-authority-data"})
+
(.users[] | select(.name == $name).user | {username, password})
Run Code Online (Sandbox Code Playgroud)
将名称作为参数传递给您的过滤器;
$ kubectl config view --raw -o json | jq --arg name some-name '
(.clusters[] | select(.name == $name).cluster | {url: .server, cert: ."certificate-authority-data"})
+
(.users[] | select(.name == $name).user | {username, password})
'
Run Code Online (Sandbox Code Playgroud)
对于问题的第二部分,如果发现映射的用户缺少关键属性而您想省略它们,只需select
在末尾添加另一个过滤器来测试这些属性,如果没有找到,则用空对象替换:
... | select(has("username") and has("password")) // {}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
214 次 |
最近记录: |