# The operator itself: one unprivileged Deployment, in the shape of
# liken's cluster operator rather than the hardware operators'
# DaemonSets. Those run a pod per node because they hold that node's
# hardware; this one holds no hardware at all.
#
# The operator serves one HTTP endpoint, the webhook Radarr,
# Sonarr, and Jellyfin post to, over the Service below. Everything else
# it hears comes over media-operator's bus, because no pod it creates
# holds an API credential and the operator alone writes a status.
#
# There is no volume for state. The operator re-derives everything
# from the API server on every pass.
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: library-operator
spec:
  replicas: 1
  selector:
    matchLabels:
      app: library-operator
  # Recreate, so two copies never reconcile at once.
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: library-operator
    spec:
      serviceAccountName: library-operator
      containers:
        - name: operator
          image: ghcr.io/liken-sh/library-operator:latest
          env:
            # The broker the operator and every pod it creates
            # reach: the bus Service that media-operator's deploy/
            # creates in this namespace. The operator cannot derive the
            # Service name, so the manifest states it, and the operator
            # passes the address into every pod it creates.
            - name: LIBRARY_BUS_ADDRESS
              value: bus.liken-system.svc:1883
            # The operator reads its own pod to learn its image, and
            # derives every companion image from it at the same tag.
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            # The namespace this pod runs in, which is what the
            # webhook address the operator reports on every Library
            # names. Nothing in a pod knows its own namespace, so the
            # downward API reads it off the pod.
            - name: OPERATOR_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            # The port the webhook endpoint answers on, behind
            # the Service below.
            - name: WEBHOOK_PORT
              value: "8080"
          ports:
            - name: webhook
              containerPort: 8080
              protocol: TCP
          securityContext:
            capabilities:
              drop: ["ALL"]
            privileged: false
            allowPrivilegeEscalation: false
          resources:
            requests:
              cpu: 10m
              memory: 32Mi
            limits:
              memory: 64Mi
---
# The one address every Library's webhook is reached at. The path
# names the Library, so one Service serves every Library in the cluster,
# and the address holds while Jobs come and go.
apiVersion: v1
kind: Service
metadata:
  name: library-operator
spec:
  selector:
    app: library-operator
  ports:
    - name: webhook
      port: 80
      targetPort: webhook
      protocol: TCP
