apiVersion: v1
kind: Namespace
metadata:
  name: community-mesh
  labels:
    app.kubernetes.io/part-of: neighborhood-isp
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: mesh-controller-config
  namespace: community-mesh
data:
  config.yaml: |
    network:
      name: "Maple Community Mesh"
      domain: "mesh.example.net"
      region: "ca-central"
      ipv4_pool: "10.42.0.0/16"
      ipv6_prefix: "fd42:6d65:7368::/48"
      mtu: 1420
    routing:
      protocol: "babel"
      convergence_interval: "5s"
      default_metric: 256
      prefer_wired_backhaul: true
    gateways:
      health_check_interval: "15s"
      failover_threshold: 3
      minimum_available: 2
    provisioning:
      node_id_prefix: "mcm"
      approval_required: true
      enrollment_token_ttl: "24h"
    monitoring:
      metrics_enabled: true
      metrics_path: "/metrics"
      anonymize_client_addresses: true
      retention_days: 30
    qos:
      enabled: true
      subscriber_downlink_mbps: 100
      subscriber_uplink_mbps: 25
      emergency_services_priority: true
---
apiVersion: v1
kind: Secret
metadata:
  name: mesh-controller-secrets
  namespace: community-mesh
type: Opaque
stringData:
  database-url: "postgresql://mesh_controller:REPLACE_ME@postgres.community-mesh.svc:5432/mesh"
  enrollment-signing-key: "REPLACE_WITH_RANDOM_64_BYTE_KEY"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mesh-controller
  namespace: community-mesh
  labels:
    app: mesh-controller
spec:
  replicas: 2
  selector:
    matchLabels:
      app: mesh-controller
  template:
    metadata:
      labels:
        app: mesh-controller
    spec:
      serviceAccountName: mesh-controller
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: controller
          image: ghcr.io/example-community/mesh-controller:2.4.1
          imagePullPolicy: IfNotPresent
          args:
            - "--config=/etc/mesh/config.yaml"
          env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: mesh-controller-secrets
                  key: database-url
            - name: ENROLLMENT_SIGNING_KEY
              valueFrom:
                secretKeyRef:
                  name: mesh-controller-secrets
                  key: enrollment-signing-key
            - name: LOG_LEVEL
              value: "info"
          ports:
            - name: api
              containerPort: 8080
            - name: metrics
              containerPort: 9090
          volumeMounts:
            - name: config
              mountPath: /etc/mesh
              readOnly: true
          readinessProbe:
            httpGet:
              path: /ready
              port: api
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /health
              port: api
            initialDelaySeconds: 20
            periodSeconds: 20
          resources:
            requests:
              cpu: 250m
              memory: 256Mi
            limits:
              cpu: "1"
              memory: 1Gi
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - ALL
            readOnlyRootFilesystem: true
      volumes:
        - name: config
          configMap:
            name: mesh-controller-config
---
apiVersion: v1
kind: Service
metadata:
  name: mesh-controller
  namespace: community-mesh
  labels:
    app: mesh-controller
spec:
  selector:
    app: mesh-controller
  ports:
    - name: api
      port: 8080
      targetPort: api
    - name: metrics
      port: 9090
      targetPort: metrics
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: mesh-controller
  namespace: community-mesh
automountServiceAccountToken: false
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: mesh-controller
  namespace: community-mesh
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: mesh-controller
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: mesh-controller
  namespace: community-mesh
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: mesh-controller
  minReplicas: 2
  maxReplicas: 6
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: mesh-controller
  namespace: community-mesh
spec:
  podSelector:
    matchLabels:
      app: mesh-controller
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: ingress-system
      ports:
        - protocol: TCP
          port: 8080
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: monitoring
      ports:
        - protocol: TCP
          port: 9090
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: postgres
      ports:
        - protocol: TCP
          port: 5432
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53