我会使用yq / jq更新kubernetes yaml文件中的几个键。这些文件包含用于kubernetes部署和服务的多个yaml文档。我已设法更新某些键的值。但我坚持更新数组中的键值对(env)。当我硬编码数组索引时,我有它工作。但这会让它变得脆弱。是否有正确的方法来查找环境名称并使用前缀更新它的值。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: zxl-portalsvc-deployment-$appEnv
spec:
replicas: 1
template:
metadata:
labels:
app: zxl-portalsvc-$appEnv
spec:
containers:
- name: zxl-portalsvc
image: artifactory.oss.oxcart.com:5000/frontface-zxl-mca:5.6.4_17
imagePullPolicy: Always
resources:
limits:
cpu: "2"
memory: 4096Mi
requests:
cpu: "1"
memory: 2048Mi
env:
- name: MYROLE
value: "zxl-portalsvc-service-$appEnv.frontface.svc.cluster.local"
- name: MYAPPS
value: "contentservices.war portalserver.war c1-integration.war"
- name: tomcat_Xmx
value: "3276m"
ports:
- containerPort: 8080
volumeMounts:
- name: frontface-configs
mountPath: /usr/local/tomcat/frontface/config
- name: sso-configs
mountPath: /usr/local/tomcat/frontface/sso-config/idp_metadata.xml
subPath: idp_metadata.xml
- name: sso-configs
mountPath: /usr/local/tomcat/frontface/sso-config/zxlKeystore.jks
subPath: zxlKeystore.jks
- name: tomcat-configs
mountPath: /usr/local/tomcat/conf/context.xml
subPath: context.xml
- name: tomcat-configs
mountPath: /usr/local/tomcat/conf/logging.properties
subPath: logging.properties
- name: tomcat-configs
mountPath: /usr/local/tomcat/conf/server.xml
subPath: server.xml
- name: tomcat-configs
mountPath: /usr/local/tomcat/conf/tomcat-users.xml
subPath: tomcat-users.xml
- name: tomcat-configs
mountPath: /usr/local/tomcat/conf/web.xml
subPath: web.xml
- name: tomcat-configs
mountPath: /usr/local/tomcat/bin/setenv.sh
subPath: setenv.sh
- name: zxl-nginxsvc
image: artifactory.oss.oxcart.com:5000/oxcart-httpauth:1.3.0
resources:
limits:
cpu: 250m
memory: 200Mi
requests:
cpu: 200m
memory: 100Mi
env:
- name: proxyDst
value: "localhost"
ports:
- containerPort: 80
volumeMounts:
- name: nginx-configs
mountPath: /etc/nginx/conf.d/nginx.htpasswd
subPath: nginx.htpasswd
- name: nginx-configs
mountPath: /etc/nginx/conf.d/default.conf
subPath: default.conf
volumes:
- name: frontface-configs
configMap:
name: frontface-config-$appEnv
- name: sso-configs
secret:
secretName: sso-config-$appEnv
- name: tomcat-configs
configMap:
name: tomcat-config-$appEnv
- name: nginx-configs
configMap:
name: nginx-config-$appEnv
---
apiVersion: v1
kind: Service
metadata:
labels:
name: zxl-portalsvc-service-$appEnv
name: zxl-portalsvc-service-$appEnv
spec:
ports:
- protocol: TCP
port: 8080
selector:
app: zxl-portalsvc-$appEnv
我有部分工作,除了它很脆弱。如果匹配不是第一个元素,那么它将会中断。有没有办法解决这个问题。也许通过识别匹配的数组索引。
这是我到目前为止所处的位置:
cat yq_test.yml | yq -y 'if .kind == "Deployment"
then (.metadata.name,.spec.template.metadata.labels.app) |= "ORG-" + "DEV-" + sub("-\\$appEnv";"") |
if .spec.template.spec.containers[].env[].name == "MYROLE" then
.spec.template.spec.containers[].env[0].value = "ORG-" + "DEV-" + .spec.template.spec.containers[].env[0].value
else empty end
elif .kind == "Service" then
(.metadata.name,.metadata.labels.name,.spec.selector.app) |= "ORG-" + "DEV-" + sub("-\\$appEnv";"")
else . end'
答案 0 :(得分:0)
使用" indexof"解决问题的方法(据我所知),对jq查询的更改很少。功能,例如:
# Returns the least integer index corresponding to
# the first element in the input array or object
# at which f is truthy, else null
def indexof(f):
label $out
| foreach .[] as $x (null;
.+1;
if ($x|f) then (.-1, break $out) else empty end)
// null;
您的查询可以按如下方式重新制作:
if .kind == "Deployment"
then (.metadata.name,.spec.template.metadata.labels.app) |=
"ORG-" + "DEV-" + sub("-\\$appEnv";"")
| (.spec.template.spec.containers[].env | indexof(.name == "MYROLE")) as $ix
| if $ix
then .spec.template.spec.containers[].env[$ix].value |= "ORG-" + "DEV-" + .
else empty
end
elif .kind == "Service"
then (.metadata.name,.metadata.labels.name,.spec.selector.app) |=
"ORG-" + "DEV-" + sub("-\\$appEnv";"")
else .
end
当然,由于使用了containers[]
,这仍然不健全。
以下假设所有" MYROLE"组件将被修改:
if .kind == "Deployment"
then (.metadata.name,.spec.template.metadata.labels.app) |=
("ORG-" + "DEV-" + sub("-\\$appEnv";""))
| .spec.template.spec as $spec
| reduce range(0; $spec.containers | length) as $c (.;
reduce range(0; $spec.containers[$c].env|length) as $ix (.;
if $spec.containers[$c].env[$ix].name == "MYROLE"
then .spec.template.spec.containers[$c].env[$ix].value |=
"ORG-" + "DEV-" + .
else .
end))
elif .kind == "Service"
then (.metadata.name,.metadata.labels.name,.spec.selector.app) |=
"ORG-" + "DEV-" + sub("-\\$appEnv";"")
else .
end
在本节中,我们将重点关注更新的目标
.containers[$i].env[$j].value
如果.containers[$i].env[$j].name
是指定值,则无论此相对路径发生在何处。
# paths for which: **.containers.*.env.*.name == $value
def relevantPaths($value):
. as $in
| paths
| select(.[-1] == "name" and .[-3] == "env" and .[-5] == "containers") as $p
| select($in|getpath($p) == $value) ;
reduce (relevantPaths("MYROLE") | ((.[-1] = "value"))) as $p (.;
setpath($p; "ORG-DEV-" + getpath($p)) )