使用 jq 从 k8s 部署中提取环境变量并按类型分组
Extract and group by type env variables from k8s deployments with jq
我正在尝试提取 k8s 部署环境变量列表,并使用 jq 和 regex 将环境变量合并到一组类别中。
例子
k8s 部署:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test
name: test
spec:
replicas: 1
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
containers:
- name: server
env:
- name: DB_MAINDB_HOST
value: maindb.example.com
- name: DB_MAINDB_DATABASE
value: test
- name: DB_MAINDB_USERNAME
value: username
- name: DB_MAINDB_PASSWORD
value: password
- name: ES_HOST
value: es-client.example.com
- name: ES_INDEX
value: test
- name: REDIS_HOST
value: redis.example.com
image: bustbox
期望输出
{
"namespace": "default",
"name": "test",
"databases": [
{
"name": "DB_MAINDB_DATABASE",
"value": "test"
},
{
"name": "DB_MAINDB_HOST",
"value": "maindb.example.com"
},
{
"name": "DB_MAINDB_PASSWORD",
"value": "password"
},
{
"name": "DB_MAINDB_USERNAME",
"value": "username"
}
],
"redis": [
{
"name": "REDIS_HOST",
"value": "redis.example.com"
}
],
"elasticsearch": [
{
"name": "ES_HOST",
"value": "es-client.example.com"
},
{
"name": "ES_INDEX",
"value": "test"
}
]
}
我尝试使用以下命令执行此操作:
kubectl get deployments test -o json | jq -r '. |
{namespace: .metadata.namespace,
name: .metadata.name,
databases: (.spec.template.spec.containers[].env | [ map(.) | .[] | select(.name | contains ("DB"))] | sort_by(.name)),
redis: (.spec.template.spec.containers[].env | [ map(.) | .[] | select(.name | contains ("REDIS"))] | sort_by(.name)),
elasticsearch: (.spec.template.spec.containers[].env | [ map(.) | .[] | select(.name | test("^(ES_).") or contains ("ELASTIC"))] | sort_by(.name)),
}'
我正在寻找一个稍微更优雅的解决方案来解决我的问题,此外,我希望能够使用相关的正则表达式作为命令的附加输入来管理类别的映射。
谢谢!
这是一个重写,其中排除了几个重复项。这是否符合您对优雅的要求,请自行判断:
(
.metadata | {namespace, name}
) + (
.spec.template.spec.containers[].env | {
databases: map(select(.name | contains ("DB"))),
redis: map(select(.name | contains ("REDIS"))),
elasticsearch: map(select(.name | test("^(ES_).") or contains ("ELASTIC")))
}
| map_values(sort_by(.name))
)
此外,您可以将排序放在前面,对未过滤的数组进行一次排序:
(
.metadata | {namespace, name}
) + (
.spec.template.spec.containers[].env | sort_by(.name) | {
databases: map(select(.name | contains ("DB"))),
redis: map(select(.name | contains ("REDIS"))),
elasticsearch: map(select(.name | test("^(ES_).") or contains ("ELASTIC")))
}
)
我正在尝试提取 k8s 部署环境变量列表,并使用 jq 和 regex 将环境变量合并到一组类别中。
例子
k8s 部署:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test
name: test
spec:
replicas: 1
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
containers:
- name: server
env:
- name: DB_MAINDB_HOST
value: maindb.example.com
- name: DB_MAINDB_DATABASE
value: test
- name: DB_MAINDB_USERNAME
value: username
- name: DB_MAINDB_PASSWORD
value: password
- name: ES_HOST
value: es-client.example.com
- name: ES_INDEX
value: test
- name: REDIS_HOST
value: redis.example.com
image: bustbox
期望输出
{
"namespace": "default",
"name": "test",
"databases": [
{
"name": "DB_MAINDB_DATABASE",
"value": "test"
},
{
"name": "DB_MAINDB_HOST",
"value": "maindb.example.com"
},
{
"name": "DB_MAINDB_PASSWORD",
"value": "password"
},
{
"name": "DB_MAINDB_USERNAME",
"value": "username"
}
],
"redis": [
{
"name": "REDIS_HOST",
"value": "redis.example.com"
}
],
"elasticsearch": [
{
"name": "ES_HOST",
"value": "es-client.example.com"
},
{
"name": "ES_INDEX",
"value": "test"
}
]
}
我尝试使用以下命令执行此操作:
kubectl get deployments test -o json | jq -r '. |
{namespace: .metadata.namespace,
name: .metadata.name,
databases: (.spec.template.spec.containers[].env | [ map(.) | .[] | select(.name | contains ("DB"))] | sort_by(.name)),
redis: (.spec.template.spec.containers[].env | [ map(.) | .[] | select(.name | contains ("REDIS"))] | sort_by(.name)),
elasticsearch: (.spec.template.spec.containers[].env | [ map(.) | .[] | select(.name | test("^(ES_).") or contains ("ELASTIC"))] | sort_by(.name)),
}'
我正在寻找一个稍微更优雅的解决方案来解决我的问题,此外,我希望能够使用相关的正则表达式作为命令的附加输入来管理类别的映射。
谢谢!
这是一个重写,其中排除了几个重复项。这是否符合您对优雅的要求,请自行判断:
(
.metadata | {namespace, name}
) + (
.spec.template.spec.containers[].env | {
databases: map(select(.name | contains ("DB"))),
redis: map(select(.name | contains ("REDIS"))),
elasticsearch: map(select(.name | test("^(ES_).") or contains ("ELASTIC")))
}
| map_values(sort_by(.name))
)
此外,您可以将排序放在前面,对未过滤的数组进行一次排序:
(
.metadata | {namespace, name}
) + (
.spec.template.spec.containers[].env | sort_by(.name) | {
databases: map(select(.name | contains ("DB"))),
redis: map(select(.name | contains ("REDIS"))),
elasticsearch: map(select(.name | test("^(ES_).") or contains ("ELASTIC")))
}
)