Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions fleet/lib/cnpg-cluster/fleet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,13 @@ targetCustomizations:
yaml:
overlays:
- yagan
- name: kueyen
clusterSelector:
matchExpressions:
- key: management.cattle.io/cluster-display-name
operator: In
values:
- kueyen
yaml:
overlays:
- kueyen
46 changes: 46 additions & 0 deletions fleet/lib/cnpg-cluster/overlays/kueyen/cluster-cnpg-cluster.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
# Cluster Definition
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cnpg-cluster
spec:
imageName: docker.io/lsstit/cnpgsphere:16.8
imagePullPolicy: Always

instances: 3

postgresql:
parameters:
max_connections: "1000"
shared_buffers: 256MB
work_mem: 8MB
effective_cache_size: 768MB
idle_session_timeout: 1h
max_slot_wal_keep_size: 1GB
pg_hba:
- host replication postgres all md5
- host all all 139.229.134.0/23 md5
- host all all 139.229.136.0/21 md5
- host all all 139.229.144.0/20 md5
- host all all 139.229.160.0/19 md5
- host all all 139.229.192.0/18 md5
- host all all 140.252.146.0/23 md5

enableSuperuserAccess: true
superuserSecret:
name: cnpg-cluster-superuser

storage:
size: 5Gi

monitoring:
enablePodMonitor: true

resources:
limits:
cpu: "1"
memory: 1Gi
requests:
cpu: "1"
memory: 1Gi
17 changes: 17 additions & 0 deletions fleet/lib/cnpg-cluster/overlays/kueyen/cnpg-loadBalancer.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
name: cnpg-loadbalancer
labels:
cnpg.io/cluster: cnpg-cluster
annotations:
metallb.universe.tf/loadBalancerIPs: 139.229.134.89
spec:
ports:
- name: postgresql
port: 5432
protocol: TCP
selector:
cnpg.io/cluster: cnpg-cluster
role: primary
type: LoadBalancer
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: cnpg-cluster-superuser
spec:
secretStoreRef:
kind: ClusterSecretStore
name: onepassword
target:
template:
type: kubernetes.io/basic-auth
data:
- secretKey: username
remoteRef:
key: cnpg-cluster-superuser-kueyen
property: username
- secretKey: password
remoteRef:
key: cnpg-cluster-superuser-kueyen
property: password
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
apiVersion: postgresql.cnpg.io/v1
kind: Pooler
metadata:
name: cnpg-cluster-pooler
namespace: cloudnativepg
spec:
cluster:
name: cnpg-cluster
instances: 3
type: rw

pgbouncer:
poolMode: session
parameters:
max_client_conn: "2000"
default_pool_size: "280"
reserve_pool_size: "20"
server_lifetime: "3600"
log_connections: "1"
log_disconnections: "1"
idle_transaction_timeout: "0"
ignore_startup_parameters: extra_float_digits

template:
metadata:
labels:
app: pooler
lsst.io/monitor: "true"
spec:
containers:
- name: pgbouncer
resources:
requests:
cpu: "0.1"
memory: 100Mi
limits:
cpu: "0.5"
memory: 500Mi
---
apiVersion: v1
kind: Service
metadata:
name: cnpg-cluster-pooler-rw
namespace: cloudnativepg
annotations:
metallb.universe.tf/loadBalancerIPs: 139.229.134.90
spec:
type: LoadBalancer
internalTrafficPolicy: Cluster
ports:
- name: pgbouncer
port: 5432
protocol: TCP
targetPort: 5432
selector:
cnpg.io/poolerName: cnpg-cluster-pooler
---
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: cnpg-cluster-pooler
namespace: cloudnativepg
labels:
lsst.io/monitor: "true"
spec:
selector:
matchLabels:
cnpg.io/poolerName: cnpg-cluster-pooler
podMetricsEndpoints:
- port: metrics
4 changes: 4 additions & 0 deletions fleet/lib/netbox/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
GEMINI.md
values-test.yaml
CLAUDE.md
WARP.md
59 changes: 59 additions & 0 deletions fleet/lib/netbox/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# NetBox Kubernetes Deployment

## Overview

NetBox is an Infrastructure Resource Modeling (IRM) application designed to empower network automation. This deployment provides a production-ready NetBox instance on Kubernetes using Helm charts and Fleet configuration management.

## Architecture

- **Chart**: netbox v6.1.5 from <https://charts.netbox.oss.netboxlabs.com/>
- **Namespace**: netbox
- **Components**: Web application, worker processes, PostgreSQL database, Valkey cache
- **Ingress**: NGINX with Let's Encrypt TLS certificates

## Configuration

### Core Settings

- **Timezone**: America/Santiago
- **Superuser**: <admin@lsst.org>
- **Change Log Retention**: 90 days
- **Job Retention**: 90 days
- **GraphQL**: Enabled
- **Login Required**: False

### Security

- Non-root container execution (UID/GID: 1000)
- Read-only root filesystem
- Dropped capabilities
- Runtime security profile enabled
- External secret management via Kubernetes secrets

### Storage

- **Persistence**: Disabled (ephemeral storage)
- **PostgreSQL**: 20Gi persistent storage (rook-ceph-block)
- **Media/Reports/Scripts**: Stored in ephemeral volumes

### Resources

| Component | CPU Request | Memory Request | CPU Limit | Memory Limit |
|-----------|-------------|----------------|-----------|--------------|
| NetBox | 500m | 1Gi | 1000m | 2Gi |
| Worker | 500m | 1Gi | 1000m | 2Gi |
| PostgreSQL| 250m | 512Mi | 500m | 1Gi |

## Access

NetBox is accessible via dynamically generated hostnames based on cluster configuration:

```bash
https://netbox.{cluster-name}.{site}.lsst.org
```

## Maintenance

- **Housekeeping**: Daily automated cleanup (00:00 UTC)
- **Job History**: 5 successful/failed jobs retained
- **Monitoring**: Available via cluster monitoring stack
24 changes: 24 additions & 0 deletions fleet/lib/netbox/base/configmap-keycloak-backend.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: netbox-keycloak-backend
namespace: netbox
data:
keycloak_backend.py: |
from social_core.backends.keycloak import KeycloakOAuth2

class KeycloakOAuth2NoJWT(KeycloakOAuth2):
"""Custom Keycloak backend that skips JWT validation"""

def public_key(self):
"""Override to skip public key validation"""
return None

def user_data(self, access_token, *args, **kwargs):
"""Get user data from userinfo endpoint without JWT validation"""
# Get USERINFO URL from settings
url = self.setting('USERINFO_URL') or self.USERINFO_URL
return self.get_json(
url,
headers={'Authorization': f'Bearer {access_token}'}
)
25 changes: 25 additions & 0 deletions fleet/lib/netbox/base/externalsecret-netbox-keycloak.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: netbox-keycloak
namespace: netbox
spec:
secretStoreRef:
kind: ClusterSecretStore
name: onepassword
target:
name: netbox-keycloak
creationPolicy: Owner
data:
- secretKey: SOCIAL_AUTH_KEYCLOAK_KEY
remoteRef:
key: &item netbox-keycloak-sso
property: client-id
- secretKey: SOCIAL_AUTH_KEYCLOAK_SECRET
remoteRef:
key: *item
property: client-secret
- secretKey: url
remoteRef:
key: *item
property: url
21 changes: 21 additions & 0 deletions fleet/lib/netbox/base/externalsecret-netbox-postgresql.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: netbox-postgresql
namespace: netbox
spec:
secretStoreRef:
kind: ClusterSecretStore
name: onepassword
target:
name: netbox-postgresql
creationPolicy: Owner
data:
- secretKey: password
remoteRef:
key: &item cnpg-cluster-superuser-kueyen
property: password
- secretKey: postgres-password
remoteRef:
key: *item
property: postgres-password
33 changes: 33 additions & 0 deletions fleet/lib/netbox/base/externalsecret-netbox-secrets.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: netbox-secrets
namespace: netbox
spec:
secretStoreRef:
kind: ClusterSecretStore
name: onepassword
target:
name: netbox-secrets
creationPolicy: Owner
data:
- secretKey: username
remoteRef:
key: &item netbox-secrets
property: username
- secretKey: password
remoteRef:
key: *item
property: password
- secretKey: email
remoteRef:
key: *item
property: email
- secretKey: api_token
remoteRef:
key: *item
property: apiToken
- secretKey: secret-key
remoteRef:
key: *item
property: secretKey
17 changes: 17 additions & 0 deletions fleet/lib/netbox/base/externalsecret-netbox-valkey.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: netbox-valkey
namespace: netbox
spec:
secretStoreRef:
kind: ClusterSecretStore
name: onepassword
target:
name: netbox-valkey
creationPolicy: Owner
data:
- secretKey: valkey-password
remoteRef:
key: &item netbox-valkey
property: password
7 changes: 7 additions & 0 deletions fleet/lib/netbox/base/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
resources:
- externalsecret-netbox-secrets.yaml
- externalsecret-netbox-valkey.yaml
- externalsecret-netbox-postgresql.yaml
- externalsecret-netbox-keycloak.yaml
- configmap-keycloak-backend.yaml
24 changes: 24 additions & 0 deletions fleet/lib/netbox/fleet.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
defaultNamespace: &name netbox
labels:
bundle: *name
namespaceLabels:
lsst.io/discover: "true"
kustomize:
dir: base
helm:
chart: &chart netbox
releaseName: *chart
repo: https://charts.netbox.oss.netboxlabs.com/
version: 6.1.5
timeoutSeconds: 600
waitForJobs: true
valuesFiles:
- values.yaml
dependsOn:
- selector:
matchLabels:
bundle: external-secrets
- selector:
matchLabels:
bundle: cnpg-cluster
Loading
Loading