使用 JQ (YQ) 在 k8s 入口清单中添加/删除后端块



我有一个 kubernetes 入口清单 YAML,如下所示:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
certmanager.k8s.io/acme-http01-edit-in-place: "true"
certmanager.k8s.io/cluster-issuer: letsencrypt
name: staging
namespace: dev
spec:
rules:
- host: staging.domain.com
http:
paths:
- backend:
serviceName: task-11111
servicePort: 80
path: /task-11111/*
- backend:
serviceName: task-22222
servicePort: 80
path: /task-22222/*
- backend:
serviceName: task-33333
servicePort: 80
path: /task-33333/*
tls:
- hosts:
- staging.domain.com
secretName: staging-domain-com

我试图实现的是添加(如果不存在)或删除(如果存在)后端块。我现在拥有的:

yq -y '.spec.rules[].http.paths += [{ "backend": { "serviceName": "'${CI_COMMIT_REF_NAME}'", "servicePort": 80}, "path": "/'${CI_COMMIT_REF_NAME}'/*"}]'

(添加一个具有变量值的新块,但如果它已经存在,则不会打扰)

yq -y 'del(.. | .paths? // empty | .[] | select(.path |contains("'${CI_COMMIT_REF_NAME}'")) )'

(失败,jq: error (at <stdin>:0): Invalid path expression with result {"backend":{"serviceName":...)

所以删除后规则可能如下所示(假设CI_COMMIT_REF_NAME=task-33333):

spec:
rules:
- host: staging.domain.com
http:
paths:
- backend:
serviceName: task-11111
servicePort: 80
path: /task-11111/*
- backend:
serviceName: task-22222
servicePort: 80
path: /task-22222/*

或者添加后像这样(假设CI_COMMIT_REF_NAME=task-44444):

spec:
rules:
- host: staging.domain.com
http:
paths:
- backend:
serviceName: task-11111
servicePort: 80
path: /task-11111/*
- backend:
serviceName: task-22222
servicePort: 80
path: /task-22222/*
- backend:
serviceName: task-33333
servicePort: 80
path: /task-33333/*
- backend:
serviceName: task-44444
servicePort: 80
path: /task-44444/*

任何帮助将不胜感激。

[以下内容已修订,以反映问题的更新。

假设 CI_COMMIT_REF_NAME 作为 $CI_COMMIT_REF_NAME 提供给 jq,这可以使用带有命令行参数的 jq 来完成:

--arg CI_COMMIT_REF_NAME "$CI_COMMIT_REF_NAME"

适当的 JQ 过滤器应遵循以下行:

.spec.rules[0].http.paths |=
(map(select(.path | index($CI_COMMIT_REF_NAME) | not)) as $new
| if ($new | length) == length
then . + [{ "backend": { "serviceName": $CI_COMMIT_REF_NAME, "servicePort": 80}, "path": ($CI_COMMIT_REF_NAME + "/*") }]
else $new
end )

您可以使用以下 jq 调用对此进行测试:

jq --arg CI_COMMIT_REF_NAME task-4444 -f program.jq input.json

当然input.json是 YAML 的 JSON 版本。

(如果可能的话,我会优先使用index而不是contains

相关内容

最新更新