apiVersion: v1 kind: ConfigMap metadata: name: netbox-plugins namespace: netbox data: plugins.py: | # NetBox Plugins Configuration PLUGINS = [ 'netbox_topology_views', 'netbox_secrets' ] PLUGINS_CONFIG = { 'netbox_topology_views': { 'static_image_directory': 'netbox_topology_views/img', 'allow_coordinates_saving': True, 'always_save_coordinates': True }, 'netbox_secrets': { 'top_level_menu': True, 'public_key_size': 2048 } } --- apiVersion: v1 kind: ConfigMap metadata: name: netbox-extra-config namespace: netbox data: extra.py: | REMOTE_AUTH_ENABLED = True REMOTE_AUTH_BACKEND = "social_core.backends.open_id_connect.OpenIdConnectAuth" SOCIAL_AUTH_OIDC_KEY = "XeeJepMAGROuSWx44nt8Kon5rAYGqBbEsFzZHkh1" SOCIAL_AUTH_OIDC_SECRET = "kp0IMfhFLRLAuhD0cfIUEbpkhrsUdEygEs9O64djg6sdAutuUmK4Wezjf8JEqovhhRUOwyIpXBWFG9q6yx62JsUzFL8KxEwx5A0xpTPw9UTI3F66wR07xeUAyBhnwKbQ" SOCIAL_AUTH_OIDC_OIDC_ENDPOINT = "https://auth.apps.undercloud.dev/application/o/netbox/" SOCIAL_AUTH_OIDC_SCOPE = ["openid", "profile", "email"] SOCIAL_AUTH_BACKEND_ATTRS = { "oidc": ("Login with Authentik", "login"), } # Optional but recommended SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL = False # Custom pipeline with group sync SOCIAL_AUTH_PIPELINE = ( "social_core.pipeline.social_auth.social_details", "social_core.pipeline.social_auth.social_uid", "social_core.pipeline.social_auth.auth_allowed", "social_core.pipeline.social_auth.social_user", "social_core.pipeline.user.get_username", "social_core.pipeline.user.create_user", "social_core.pipeline.social_auth.associate_user", "social_core.pipeline.social_auth.load_extra_data", "social_core.pipeline.user.user_details", "netbox.custom_pipeline.add_groups", "netbox.custom_pipeline.remove_groups", "netbox.custom_pipeline.set_roles", ) LOGOUT_REDIRECT_URL = "https://auth.apps.undercloud.dev/application/o/netbox/end-session/" --- apiVersion: v1 kind: ConfigMap metadata: name: netbox-auth-pipeline namespace: netbox data: custom_pipeline.py: | from netbox.authentication import Group def add_groups(response, user, backend, *args, **kwargs): wanted = set(response.get("groups", [])) for group_name in wanted: group, _ = Group.objects.get_or_create(name=group_name) user.groups.add(group) def remove_groups(response, user, backend, *args, **kwargs): wanted = set(response.get("groups", [])) current = {g.name for g in user.groups.all()} for delete_group in current - wanted: group = Group.objects.get(name=delete_group) user.groups.remove(group) def set_roles(response, user, backend, *args, **kwargs): groups = set(response.get("groups", [])) is_admin = "undercloud-administrators" in groups user.is_superuser = is_admin user.is_staff = is_admin user.save() --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: netbox namespace: netbox spec: accessModes: - ReadWriteMany resources: requests: storage: 64Gi storageClassName: cephfs-hyper --- apiVersion: apps/v1 kind: Deployment metadata: name: netbox namespace: netbox spec: replicas: 1 selector: matchLabels: app: netbox template: metadata: labels: app: netbox spec: securityContext: runAsUser: 999 runAsGroup: 0 fsGroup: 0 containers: - name: netbox image: docker-repo.apps.undercloud.dev/library/netbox-custom:latest imagePullPolicy: Always ports: - containerPort: 8080 name: http env: - name: SUPERUSER_NAME valueFrom: secretKeyRef: name: netbox-superuser key: username - name: SUPERUSER_EMAIL valueFrom: secretKeyRef: name: netbox-superuser key: email - name: SUPERUSER_PASSWORD valueFrom: secretKeyRef: name: netbox-superuser key: password - name: DB_NAME value: netbox - name: DB_HOST value: db - name: DB_PORT value: "5432" - name: DB_USER valueFrom: secretKeyRef: name: netbox-db key: username - name: DB_PASSWORD valueFrom: secretKeyRef: name: netbox-db key: user.pw - name: DB_WAIT_DEBUG value: "1" - name: REDIS_HOST value: redis - name: REDIS_PORT value: "6379" - name: REDIS_CACHE_HOST value: redis - name: REDIS_CACHE_PORT value: "6379" - name: SECRET_KEY valueFrom: secretKeyRef: name: netbox-secrets key: SECRET_KEY - name: ALLOWED_HOSTS value: "*" volumeMounts: - name: netbox-data mountPath: /opt/netbox/netbox/media - name: netbox-plugins-config mountPath: /etc/netbox/config/plugins.py subPath: plugins.py readOnly: true - name: netbox-extra-config mountPath: /etc/netbox/config/extra.py subPath: extra.py readOnly: true - name: netbox-auth-pipeline mountPath: /opt/netbox/netbox/netbox/custom_pipeline.py subPath: custom_pipeline.py readOnly: true startupProbe: httpGet: path: / port: 8080 failureThreshold: 30 periodSeconds: 10 readinessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 5 periodSeconds: 10 livenessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 120 periodSeconds: 20 volumes: - name: netbox-data persistentVolumeClaim: claimName: netbox - name: netbox-plugins-config configMap: name: netbox-plugins - name: netbox-extra-config configMap: name: netbox-extra-config - name: netbox-auth-pipeline configMap: name: netbox-auth-pipeline --- apiVersion: v1 kind: Service metadata: name: netbox namespace: netbox labels: app: netbox netbox-export: "true" spec: internalTrafficPolicy: Cluster ipFamilies: - IPv6 - IPv4 ipFamilyPolicy: PreferDualStack type: ClusterIP selector: app: netbox ports: - name: http port: 80 protocol: TCP targetPort: 8080