繁体   English   中英

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

[英]ADD / REMOVE a backend block within k8s ingress manifest with JQ (YQ)

我有一个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":...失败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 。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM