Das Schweitzer Messer für YAML – yq

yq ist das Schweizer Messer für YAML Dateien

Leider gibt es zwei Programme die den Namen yq besitzen und auch den selben Zweck erfüllen. Beide Programme behandeln YAML Dateien auf der Konsole.

In diesem Artikel beschreibe ich die Version von Mike Farah. Für Arch basierende Distributionen wie Manjaro gibt es yq allerdings noch nicht.

Das PKGBUILD

Leider gibt es im AUR Repository noch keinen Eintrag, sodass ich kurzerhand das folgende PKGBUILD zusammengestrikt habe.

# Maintainer: Sascha Pfau

pkgname=yq
pkgdesc="portable command-line YAML processor written in Go"
pkgver=3.3.4
pkgrel=0
arch=('i686' 'x86_64')
url="https://github.com/mikefarah/yq"
license=('MIT')
makedepends=('go' 'rsync')
source=("https://github.com/mikefarah/yq/archive/${pkgver}.tar.gz")
sha256sums=('b0c44a742a9b6eed25a48ff04bb30e3e05c6c2d5a0c869f9d0d7f778dfd40f05')

# See https://wiki.archlinux.org/index.php/Go_package_guidelines
prepare(){
  cd "$pkgname-$pkgver"
  mkdir -p build
}

build() {
  cd "$pkgname-$pkgver"
  GOPATH="$srcdir" go build -v 
}

package() {
  install -Dm755 "$pkgname-$pkgver"/$pkgname "$pkgdir"/usr/bin/$pkgname
}

Funktionsübersicht

In der folgenden Tabelle sind die grundlegenden Kommandos aufgeführt.

Kommando Beschreibung
read Werte auslesen
validate
compare YAML Dateien vergleichen
write Werte schreibe
create YAML Dateien erstellen
delete
merge
prefix

Bash completion

Kubernetes Konfiguration bearbeiten

Da Kubernetes die Manifeste in YAML Dateien sichert und einliest, eignet sich yq hervoragend um diese zu bearbeiten. Die herkömmlichen Tools awk, sed etc. kommen hier schnell an ihre Grenzen. Zumal yq auch mit multi document YAML Dateien umgehen kann.

Beispiel

In dem Beispiel verwende ich ein Gitea Konfiguration die aus einem Dokument besteht.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: gitea
  namespace: env
  labels:
    name: gitea
spec:
  replicas: 1
  strategy:
    rollingUpdate:
      maxSurge: 0
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        name: gitea
    spec:
      # Initial rights settings when creating disk can be incorrect
      # for the git user in the gitea container: Use init container to set the rights
      initContainers:
        - name: init-disk
          image: busybox:latest
          command:
            - /bin/chown
            - 1000:1000
            - /data
          volumeMounts:
            - name: gitea
              mountPath: "/data"
      containers:
        - name: gitea
          image: "gitea/gitea:latest"
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 3000
            - containerPort: 22
          volumeMounts:
            - name: gitea
              mountPath: "/data"
            - name: gitea-config
              mountPath: /data/gitea/conf
          resources:
            requests:
              cpu: 10m
              memory: 50Mi
            limits:
              cpu: 1
              memory: 200Mi
      volumes:
        - name: gitea
          persistentVolumeClaim:
            claimName: gitea
        - name: gitea-config
          configMap:
            name: gitea-config
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: gitea-ingress
  namespace: gitea
  annotations:
    traefik.ingress.kubernetes.io/affinity: "true"
spec:
  rules:
    - host: k8s-gitea.domain.duckdns.org
      http:
        paths:
          - backend:
              serviceName: gitea
              servicePort: 443
            path: /
---
apiVersion: v1
kind: Service
metadata:
  name: gitea
  namespace: env
  labels:
    name: gitea
spec:
  ports:
    - name: gitea
      port: 443
      targetPort: 3000
    - name: gitea-ssh
      port: 22
      targetPort: 22
  selector:
    name: gitea
  type: ClusterIP
  sessionAffinity: ClientIP
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  labels:
    app: gitea
  name: gitea
  namespace: gitea
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Mi
---
apiVersion: v1
kind: Namespace
metadata:
  labels:
    name: gitea
  name: gitea

Für die Nutzung des Manifests sind zuvor noch der Host in dem Ingress angepasst werden.

Host lesen

yq r -d1 install.yaml spec.rules[0].host

Gibt den Value des Hosts aus:

k8s-gitea.domain.duckdns.org  

Host überschreiben

yq w -i -d1 install.yaml spec.rules[0].host k8s-gitea.neuedomain.duckdns.org