Skip to content

Commit

Permalink
Add bin/show-docker-images.py (#2101)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielhoherd authored and pgvishnuram committed Feb 5, 2024
1 parent c4cbbf0 commit 58e1990
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 19 deletions.
14 changes: 2 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,8 @@ update-requirements: ## Update all requirements.txt files

.PHONY: show-docker-images
show-docker-images: ## Show all docker images and versions used in the helm chart
@helm template . \
-f tests/enable_all_features.yaml \
--set forceIncompatibleKubernetes=true \
2>/dev/null \
| gawk '/image: / {match($$2, /(([^"]*):[^"]*)/, a) ; printf "https://%s %s\n", a[2], a[1] ;}' | sort -u | column -t
@bin/show-docker-images.py --with-houston

.PHONY: show-docker-images-with-private-registry
show-docker-images-with-private-registry: ## Show all docker images and versions used in the helm chart with a privateRegistry set
@helm template . \
-f tests/enable_all_features.yaml \
--set forceIncompatibleKubernetes=true \
--set global.privateRegistry.enabled=True \
--set global.privateRegistry.repository=example.com/the-private-registry \
2>/dev/null \
| gawk '/image: / {match($$2, /(([^"]*):[^"]*)/, a) ; printf "https://%s %s\n", a[2], a[1] ;}' | sort -u | column -t
@bin/show-docker-images.py --private-registry --with-houston
147 changes: 147 additions & 0 deletions bin/show-docker-images.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
#!/usr/bin/env python3
"""Show a list of docker images that are deployed by the astronomer platform."""

import subprocess
from pathlib import Path
import yaml
import argparse
import sys
import json


def get_containers_from_spec(spec):
"""Return a list of images used in a kubernetes pod spec."""
return [
container["image"]
for container in spec.get("containers", []) + spec.get("initContainers", [])
]


def print_results(items):
"""Print an HTTPS url and the docker pull URL for every image in the list."""
splits = [image_tag.split(":") for image_tag in items]
max_length = max(len(x[0]) for x in splits)
for image, tag in splits:
print(f"https://{image:{max_length}} {image}:{tag}")


def default_spec_parser(doc, args):
"""Parse and report on Deployments, StatefulSets, and DaemonSets."""

item_containers = get_containers_from_spec(doc["spec"]["template"]["spec"])

if args.verbose:
print(f"Processing {doc['kind']} {doc['metadata']['name']}", file=sys.stderr)

if args.private_registry and "quay.io" in yaml.dump(item_containers):
print(
f'{doc["kind"]} {doc["metadata"]["name"].removeprefix("release-name-")} uses quay.io instead of private registry'
)
if args.verbose:
print(json.dumps(doc["spec"]["template"]["spec"]), file=sys.stderr)

return item_containers


def job_template_spec_parser(doc, args):
"""Parse and report on CronJobs, which have a different structure than other pod managers."""

if args.verbose:
print(f"Processing {doc['kind']} {doc['metadata']['name']}", file=sys.stderr)

item_containers = get_containers_from_spec(
doc["spec"]["jobTemplate"]["spec"]["template"]["spec"]
)

if args.private_registry and "quay.io" in yaml.dump(item_containers):
print(
f'{doc["kind"]} {doc["metadata"]["name"].removeprefix("release-name-")} uses quay.io instead of private registry'
)
if args.verbose:
print(
json.dumps(doc["spec"]["jobTemplate"]["spec"]["template"]["spec"]),
file=sys.stderr,
)

return item_containers


def get_images_from_houston_configmap(doc, args):
"""Return a list of images used in the houston configmap."""
houston_config = yaml.safe_load(doc["data"]["production.yaml"])
keepers = ("authSideCar", "loggingSidecar")
items = {k: v for k, v in houston_config["deployments"].items() if k in keepers}
auth_sidecar_image = (
f'{items["authSideCar"]["repository"]}:{items["authSideCar"]["tag"]}'
)
logging_sidecar_image = f'{items["loggingSidecar"]["image"]}'
images = (auth_sidecar_image, logging_sidecar_image)
if args.verbose and any("quay.io" in x for x in images):
print(
"Houston configmap uses quay.io instead of private registry",
file=sys.stderr,
)
return images


def helm_template(args):
"""Run helm template and return the parsed yaml."""
GIT_ROOT = next(
iter([x for x in Path(__file__).resolve().parents if (x / ".git").is_dir()]),
None,
)

command = "helm template . --set forceIncompatibleKubernetes=true -f tests/enable_all_features.yaml"
if args.private_registry:
command += (
" --set global.privateRegistry.repository=example.com/the-private-registry"
" --set global.privateRegistry.enabled=True"
)

if args.verbose:
print(f"Running command: {command}", flush=True, file=sys.stderr)
output = subprocess.check_output(command, shell=True, cwd=GIT_ROOT).decode("utf-8")

return list(yaml.safe_load_all(output))


def main():
"""Parse the helm output and print the images."""

parser = argparse.ArgumentParser()
parser.add_argument(
"--private-registry",
action="store_true",
help="show images when using private registry",
)
parser.add_argument("-v", "--verbose", action="store_true", help="be verbose")
parser.add_argument(
"--with-houston",
action="store_true",
help="include images from houston configmap",
)
args = parser.parse_args()

docs = helm_template(args)

containers = set()

for doc in docs:
if doc is None:
continue
match doc:
case {"spec": {"template": {"spec": _}}}:
containers.update(default_spec_parser(doc, args))
case {"spec": {"jobTemplate": {"spec": {"template": {"spec": _}}}}}:
containers.update(job_template_spec_parser(doc, args))
case {"metadata": {"name": "release-name-houston-config"}}:
if args.with_houston:
containers.update(get_images_from_houston_configmap(doc, args))
case _:
pass

print_results(sorted(containers))


if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ spec:
{{- end }}
{{- if .Values.global.authSidecar.enabled }}
- name: auth-proxy
image: "{{ .Values.global.authSidecar.repository }}:{{ .Values.global.authSidecar.tag }}"
image: {{ include "authSidecar.image" . }}
securityContext: {{ toYaml .Values.securityContext| nindent 12 }}
imagePullPolicy: {{ .Values.global.authSidecar.pullPolicy }}
{{- if .Values.global.authSidecar.resources }}
Expand Down
7 changes: 4 additions & 3 deletions charts/astronomer/templates/houston/houston-configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,11 @@ data:
{{- if .Values.global.authSidecar.enabled }}
# enables nginx auth sidecar for airflow deployments
{{- $authSidecar := include "authSidecar.image" . }}
authSideCar:
enabled: true
repository: {{ .Values.global.authSidecar.repository }}
tag: {{ .Values.global.authSidecar.tag }}
repository: {{ (splitList ":" $authSidecar ) | first }}
tag: {{ (splitList ":" $authSidecar ) | last }}
port: {{ .Values.global.authSidecar.port }}
pullPolicy: {{ .Values.global.authSidecar.pullPolicy }}
annotations: {
Expand All @@ -118,7 +119,7 @@ data:
loggingSidecar:
enabled: true
name: {{ .Values.global.loggingSidecar.name }}
image: {{ .Values.global.loggingSidecar.image }}
image: {{ include "loggingSidecar.image" . }}
customConfig: {{ .Values.global.loggingSidecar.customConfig }}
{{- if .Values.global.loggingSidecar.extraEnv}}
extraEnv: {{- .Values.global.loggingSidecar.extraEnv | toYaml | nindent 8 }}
Expand Down
2 changes: 1 addition & 1 deletion charts/grafana/templates/grafana-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ spec:
{{- end }}
{{- if .Values.global.authSidecar.enabled }}
- name: auth-proxy
image: "{{ .Values.global.authSidecar.repository }}:{{ .Values.global.authSidecar.tag }}"
image: {{ include "authSidecar.image" . }}
securityContext: {{ toYaml .Values.securityContext| nindent 12 }}
imagePullPolicy: {{ .Values.global.authSidecar.pullPolicy }}
{{- if .Values.global.authSidecar.resources }}
Expand Down
2 changes: 1 addition & 1 deletion charts/kibana/templates/kibana-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ spec:
protocol: TCP
{{- if .Values.global.authSidecar.enabled }}
- name: auth-proxy
image: "{{ .Values.global.authSidecar.repository }}:{{ .Values.global.authSidecar.tag }}"
image: {{ include "authSidecar.image" . }}
securityContext: {{ template "kibana.securityContext" . }}
imagePullPolicy: {{ .Values.global.authSidecar.pullPolicy }}
{{- if .Values.global.authSidecar.resources }}
Expand Down
2 changes: 1 addition & 1 deletion charts/prometheus/templates/prometheus-statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ spec:
containers:
{{- if .Values.global.authSidecar.enabled }}
- name: auth-proxy
image: "{{ .Values.global.authSidecar.repository }}:{{ .Values.global.authSidecar.tag }}"
image: {{ include "authSidecar.image" . }}
securityContext: {{ template "prometheus.securityContext" . }}
imagePullPolicy: {{ .Values.global.authSidecar.pullPolicy }}
{{- if .Values.global.authSidecar.resources }}
Expand Down
16 changes: 16 additions & 0 deletions templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,19 @@ nginx.ingress.kubernetes.io/auth-url: https://houston.{{ .Values.global.baseDoma
{{ .Values.global.dagOnlyDeployment.image }}
{{- end }}
{{- end }}

{{ define "authSidecar.image" -}}
{{- if .Values.global.privateRegistry.enabled -}}
{{ .Values.global.privateRegistry.repository }}/ap-auth-sidecar:{{ .Values.global.authSidecar.tag }}
{{- else -}}
{{ .Values.global.authSidecar.repository }}:{{ .Values.global.authSidecar.tag }}
{{- end }}
{{- end }}

{{ define "loggingSidecar.image" -}}
{{- if .Values.global.privateRegistry.enabled -}}
{{ .Values.global.privateRegistry.repository }}/ap-vector:{{ (splitList ":" .Values.global.loggingSidecar.image ) | last }}
{{- else -}}
{{ .Values.global.loggingSidecar.image }}
{{- end }}
{{- end }}

0 comments on commit 58e1990

Please sign in to comment.