├── .codeclimate.yml ├── Dockerfile ├── README.md └── run.sh /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | --- 2 | engines: 3 | shellcheck: 4 | enabled: true 5 | markdownlint: 6 | enabled: true 7 | ratings: 8 | paths: [] 9 | exclude_paths: [] 10 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | 3 | MAINTAINER Trevor Hartman 4 | 5 | RUN apk --update add curl bash 6 | 7 | ADD run.sh /run.sh 8 | 9 | CMD /run.sh 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # k8s-labeler 2 | 3 | [![Code Climate](https://img.shields.io/codeclimate/issues/github/devth/k8s-labeler.svg?style=flat-square)](https://codeclimate.com/github/devth/k8s-labeler) 4 | [![Docker Automated build](https://img.shields.io/docker/automated/devth/k8s-labeler.svg?style=flat-square)](https://hub.docker.com/r/devth/k8s-labeler/) 5 | 6 | Intended to be used as an init container for a Kubernetes pod. 7 | 8 | ## Usage 9 | 10 | The `KUBE_NAMESPACE` env var is **required**. This must match the namespace of 11 | the pod you're running in. 12 | 13 | Any env vars containing `KUBE_LABEL_` will be applied to the pod as labels via 14 | the API. For example: 15 | 16 | ```bash 17 | KUBE_LABEL_hostname=foobar 18 | ``` 19 | 20 | Would result in a label `hostname: foobar` on the pod. 21 | 22 | This can be useful for setting properties from the [Downward 23 | API](https://kubernetes.io/docs/tasks/configure-pod-container/environment-variable-expose-pod-information/) 24 | as labels (e.g. exposing a unique label for each pod in a stateful). 25 | 26 | ## Run locally 27 | 28 | ```bash 29 | ./run.sh 30 | ``` 31 | 32 | ## Kubernetes example 33 | 34 | This init container sets a `hostname` label equal to the pod's name: 35 | 36 | ```yaml 37 | initContainers: 38 | - image: devth/k8s-labeler 39 | name: labeler 40 | env: 41 | - name: KUBE_NAMESPACE 42 | valueFrom: 43 | fieldRef: 44 | fieldPath: metadata.namespace 45 | - name: KUBE_LABEL_hostname 46 | valueFrom: 47 | fieldRef: 48 | fieldPath: metadata.name 49 | ``` 50 | 51 | Inspect the pod with: 52 | 53 | ```bash 54 | kubectl get pod -l app=myapp --show-labels 55 | 56 | NAME READY STATUS RESTARTS AGE LABELS 57 | myapp-2768796676-c702s 2/2 Running 0 25m app=myapp,hostname=myapp-2768796676-c702s,pod-template-hash=2768796676 58 | ``` 59 | 60 | And notice that the `hostname=myapp-2768796676-c702s` label is present. 61 | 62 | ## License 63 | 64 | Copyright 2017 Trevor C. Hartman 65 | 66 | Permission is hereby granted, free of charge, to any person obtaining a copy of 67 | this software and associated documentation files (the "Software"), to deal in 68 | the Software without restriction, including without limitation the rights to 69 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 70 | the Software, and to permit persons to whom the Software is furnished to do so, 71 | subject to the following conditions: 72 | 73 | The above copyright notice and this permission notice shall be included in all 74 | copies or substantial portions of the Software. 75 | 76 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 77 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 78 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 79 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 80 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 81 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 82 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | # Validate env vars {{{ 6 | 7 | KUBE_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) 8 | if [ -z "$KUBE_TOKEN" ]; then 9 | echo "Error: KUBE_TOKEN is empty" 10 | exit 1 11 | fi 12 | 13 | if [ -z "$KUBE_NAMESPACE" ]; then 14 | echo "Error: KUBE_NAMESPACE is empty" 15 | exit 1 16 | fi 17 | 18 | HOSTNAME=$(hostname) 19 | 20 | # }}} 21 | 22 | # Parse labels from ENV and build up a json patch {{{ 23 | 24 | unset IFS 25 | 26 | echo > patch.json 27 | echo "[" >> patch.json 28 | for var in $(compgen -e | grep KUBE_LABEL_); do 29 | echo "$var = ${!var}" 30 | label_name="${var//KUBE_LABEL_/}" 31 | { 32 | echo '{'; 33 | echo ' "op":"add", "path":"/metadata/labels/'"$label_name"'", "value":"'"${!var}"'"' 34 | echo '},' 35 | } >> patch.json 36 | done 37 | sed -i '$ s/.$//' patch.json 38 | echo "]" >> patch.json 39 | cat patch.json 40 | 41 | # }}} 42 | 43 | # Apply {{{ 44 | 45 | api_url="https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_PORT_443_TCP_PORT/api/v1/namespaces/$KUBE_NAMESPACE/pods/$HOSTNAME" 46 | 47 | echo "Applying JSON patch:" 48 | cat patch.json 49 | echo "at $api_url" 50 | 51 | curl -sSk --request PATCH --data "$(cat patch.json)" \ 52 | -H "Authorization: Bearer $KUBE_TOKEN" \ 53 | -H "Content-Type:application/json-patch+json" \ 54 | "$api_url" 55 | 56 | # }}} 57 | --------------------------------------------------------------------------------