# FlowerCore Apple MDM NanoHUB workload for the GX10 cluster. # Secret values are copied into Kubernetes Secrets out of band until the # 1Password operator exists on GX10; never commit secret data here. --- apiVersion: v1 kind: Namespace metadata: name: fc-apple-mdm labels: app.kubernetes.io/part-of: flowercore --- apiVersion: v1 kind: ConfigMap metadata: name: fc-apple-mdm-root-ca namespace: fc-apple-mdm data: root_ca.crt: | -----BEGIN CERTIFICATE----- MIIBxDCCAWqgAwIBAgIRAPY357G6ow6zMAL5+4bS2kkwCgYIKoZIzj0EAwIwQDEa MBgGA1UEChMRSUFtV29ya2luIEFDTUUgQ0ExIjAgBgNVBAMTGUlBbVdvcmtpbiBB Q01FIENBIFJvb3QgQ0EwHhcNMjYwMzA4MTgwNzExWhcNMzYwMzA1MTgwNzExWjBA MRowGAYDVQQKExFJQW1Xb3JraW4gQUNNRSBDQTEiMCAGA1UEAxMZSUFtV29ya2lu IEFDTUUgQ0EgUm9vdCBDQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2n04X1 JZo5Zdq/i1Idv8+fqwZyAzBh7whbqj0SWsJL8UWRabCMqYCs7+dXO0xRSzqkwFDL x+vooOai8RgRNhajRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/ AgEBMB0GA1UdDgQWBBRnuPPQR6iM/H6vOluiU3Sygayz8jAKBggqhkjOPQQDAgNI ADBFAiEArQK9dYPGmAZsdYnjziuFVVE5NKZUcceYvGfGC+tLXUsCIAudF2zJrCRq 3mK50ZZET/fwTkJwiEF4824mjP8p1CKM -----END CERTIFICATE----- --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: fc-apple-mdm-data namespace: fc-apple-mdm labels: app: fc-apple-mdm app.kubernetes.io/name: fc-apple-mdm app.kubernetes.io/part-of: flowercore spec: accessModes: - ReadWriteOnce storageClassName: local-path resources: requests: storage: 2Gi --- apiVersion: apps/v1 kind: Deployment metadata: name: fc-apple-mdm namespace: fc-apple-mdm labels: app: fc-apple-mdm app.kubernetes.io/name: fc-apple-mdm app.kubernetes.io/component: mdm app.kubernetes.io/part-of: flowercore spec: replicas: 1 revisionHistoryLimit: 3 strategy: type: Recreate selector: matchLabels: app: fc-apple-mdm template: metadata: labels: app: fc-apple-mdm app.kubernetes.io/name: fc-apple-mdm app.kubernetes.io/component: mdm app.kubernetes.io/part-of: flowercore annotations: fc.flowercore.io/healthz-anon: "true" fc.flowercore.io/probe-path: "/version" flowercore.io/audit-trace-id: "apple-mdm-nanohub-runtime-trace" flowercore.io/root-ca-sha256: "a9120c88fa3ec735d790aa4cfeb61ac2946730338969015bebaccc08fe10535e" prometheus.io/scrape: "false" spec: enableServiceLinks: false securityContext: runAsNonRoot: true runAsUser: 1654 runAsGroup: 1654 fsGroup: 1654 fsGroupChangePolicy: OnRootMismatch containers: - name: nanohub image: localhost/fc-apple-mdm-nanohub:v0.2.0-20260617 imagePullPolicy: Never ports: - name: http containerPort: 9004 protocol: TCP env: - name: HOME value: "/var/lib/nanohub" - name: NANOHUB_LISTEN value: ":9004" - name: NANOHUB_STORAGE value: "file" - name: NANOHUB_STORAGE_DSN value: "/var/lib/nanohub/db" - name: NANOHUB_CHECKIN value: "true" - name: NANOHUB_CA value: "/etc/nanohub/ca/root_ca.crt" - name: NANOHUB_API_KEY valueFrom: secretKeyRef: name: fc-apple-mdm-runtime key: NANOHUB_API_KEY - name: NANOHUB_WEBHOOK_URL valueFrom: secretKeyRef: name: fc-apple-mdm-runtime key: NANOHUB_WEBHOOK_URL optional: true resources: requests: cpu: 50m memory: 128Mi limits: cpu: 500m memory: 512Mi startupProbe: httpGet: path: /version port: 9004 initialDelaySeconds: 5 periodSeconds: 5 failureThreshold: 30 readinessProbe: httpGet: path: /version port: 9004 periodSeconds: 10 failureThreshold: 3 livenessProbe: tcpSocket: port: 9004 initialDelaySeconds: 30 periodSeconds: 30 failureThreshold: 3 securityContext: runAsNonRoot: true runAsUser: 1654 runAsGroup: 1654 allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL volumeMounts: - name: data mountPath: /var/lib/nanohub - name: tmp mountPath: /tmp - name: root-ca mountPath: /etc/nanohub/ca readOnly: true volumes: - name: data persistentVolumeClaim: claimName: fc-apple-mdm-data - name: tmp emptyDir: {} - name: root-ca configMap: name: fc-apple-mdm-root-ca items: - key: root_ca.crt path: root_ca.crt --- apiVersion: v1 kind: Service metadata: name: fc-apple-mdm namespace: fc-apple-mdm labels: app: fc-apple-mdm app.kubernetes.io/name: fc-apple-mdm app.kubernetes.io/part-of: flowercore spec: type: ClusterIP selector: app: fc-apple-mdm ports: - name: http port: 80 targetPort: 9004 protocol: TCP --- apiVersion: v1 kind: Service metadata: name: fc-apple-mdm-scep namespace: fc-apple-mdm labels: app: fc-apple-mdm-scep app.kubernetes.io/name: fc-apple-mdm-scep app.kubernetes.io/part-of: flowercore spec: type: ClusterIP ports: - name: http port: 80 targetPort: 9080 protocol: TCP --- apiVersion: discovery.k8s.io/v1 kind: EndpointSlice metadata: name: fc-apple-mdm-scep-noc1 namespace: fc-apple-mdm labels: kubernetes.io/service-name: fc-apple-mdm-scep app.kubernetes.io/name: fc-apple-mdm-scep app.kubernetes.io/part-of: flowercore addressType: IPv4 endpoints: - addresses: - 10.0.56.10 conditions: ready: true ports: - name: http port: 9080 protocol: TCP --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: fc-apple-mdm-tls namespace: fc-apple-mdm annotations: flowercore.io/dns-preflight: "mdm.iamworkin.lan must resolve to 10.0.57.202 before ACME sync" spec: secretName: fc-apple-mdm-tls issuerRef: name: step-ca-acme kind: ClusterIssuer dnsNames: - mdm.iamworkin.lan duration: 720h renewBefore: 240h --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: fc-apple-mdm namespace: fc-apple-mdm spec: entryPoints: - websecure routes: - match: Host(`mdm.iamworkin.lan`) && PathPrefix(`/scep`) kind: Rule services: - name: fc-apple-mdm-scep port: 80 - match: Host(`mdm.iamworkin.lan`) && (PathPrefix(`/mdm`) || PathPrefix(`/checkin`) || PathPrefix(`/version`)) kind: Rule services: - name: fc-apple-mdm port: 80 tls: secretName: fc-apple-mdm-tls --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: fc-apple-mdm-netpol namespace: fc-apple-mdm spec: podSelector: matchLabels: app: fc-apple-mdm policyTypes: - Ingress - Egress ingress: - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: traefik-system ports: - port: 9004 protocol: TCP - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: fc-devicemgmt ports: - port: 9004 protocol: TCP egress: - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system ports: - port: 53 protocol: UDP - port: 53 protocol: TCP - to: - ipBlock: cidr: 0.0.0.0/0 ports: - port: 443 protocol: TCP - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: fc-devicemgmt ports: - port: 80 protocol: TCP - port: 8080 protocol: TCP