Skip to content

Commit e5ac686

Browse files
authored
Merge pull request #14 from baseVISION/release/2.5.0-bv2
Release v2.5.0-bv2
2 parents d559008 + 99c8983 commit e5ac686

287 files changed

Lines changed: 45204 additions & 3462 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.model

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,31 @@
11
# -- COMMON
22
LOG_LEVEL=info
33

4+
# -- HOSTNAME (single source of truth)
5+
# When set, IRIS_HOSTNAME provides fallback defaults for SERVER_NAME
6+
# (nginx), PUBLIC_EXTERNAL_API_URL / ORIGIN (SvelteKit), and
7+
# VITE_ALLOWED_HOSTS (Vite dev). Explicit values still take precedence
8+
# for split-hostname deployments (e.g. API on a different host than UI).
9+
# Existing .env files that set the four vars individually keep working.
10+
#IRIS_HOSTNAME=iris.app.dev
11+
412
# -- NGINX
513
NGINX_IMAGE_NAME=ghcr.io/dfir-iris/iriswebapp_nginx
614

715
SERVER_NAME=iris.app.dev
16+
# When both KEY_FILENAME and CERT_FILENAME are unset AND certbot's
17+
# standard fullchain.pem + privkey.pem pair exist under
18+
# ./certificates/web_certificates/, the nginx entrypoint autodetects
19+
# them — useful for Let's Encrypt setups. See
20+
# scripts/certbot-deploy-hook.sh for zero-copy renewals.
821
KEY_FILENAME=iris_dev_key.pem
922
CERT_FILENAME=iris_dev_cert.pem
1023

24+
# Nginx polls the cert file's mtime every N seconds and reloads on
25+
# change so certbot renewals apply without a container restart. Set
26+
# to 0 to disable if your deployment reloads nginx externally.
27+
#IRIS_CERT_RELOAD_INTERVAL=60
28+
1129
# -- DATABASE
1230
DB_IMAGE_NAME=ghcr.io/dfir-iris/iriswebapp_db
1331

@@ -88,6 +106,23 @@ IRIS_AUTHENTICATION_TYPE=local
88106
# optional mapping for usergroup-names
89107
# OIDC_MAPPING_USERGROUP= "iris-roles" #Group field in OIDC Token
90108
# OIDC_MAPPING_ROLES= '{"iris-admin": "1", "iris-analyst": "2"}'
109+
# -- CUSTOM CA CERTIFICATES (Keycloak, LDAPS, webhooks, ...)
110+
# The recommended way to trust internal CAs is to drop one or more
111+
# *.crt / *.pem files into ./certificates/ca-bundle/ on the host —
112+
# they are mounted at /etc/iris-ca/ inside the app and worker
113+
# containers, and the entrypoint installs them into the OS trust
114+
# store (update-ca-certificates) on every boot. This is ADDITIVE:
115+
# system roots stay trusted, so no manual concatenation is needed.
116+
#
117+
# The legacy single-file bundle at
118+
# ./certificates/ca-bundle/extra-ca.crt is still honoured for
119+
# backward compatibility, as are the REQUESTS_CA_BUNDLE /
120+
# SSL_CERT_FILE / TLS_ROOT_CA env vars (which REPLACE the default
121+
# trust store rather than augmenting it — prefer the drop-in dir
122+
# unless you have a reason to pin the exact bundle).
123+
#REQUESTS_CA_BUNDLE=/etc/iris-ca/extra-ca.crt
124+
#SSL_CERT_FILE=/etc/iris-ca/extra-ca.crt
125+
91126
# -- LISTENING PORT
92127
INTERFACE_HTTPS_PORT=443
93128

.github/workflows/ci.yml

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -110,43 +110,6 @@ jobs:
110110
name: iriswebapp_app
111111
path: ${{ runner.temp }}/iriswebapp_app.tar
112112

113-
build-graphql-documentation:
114-
name: Generate graphQL documentation
115-
runs-on: ubuntu-22.04
116-
needs:
117-
- build-docker-db
118-
- build-docker-nginx
119-
- build-docker-app
120-
steps:
121-
- name: Download artifacts
122-
uses: actions/download-artifact@v4
123-
with:
124-
pattern: iriswebapp_*
125-
path: ${{ runner.temp }}
126-
merge-multiple: true
127-
- name: Load docker images
128-
run: |
129-
docker load --input ${{ runner.temp }}/iriswebapp_db.tar
130-
docker load --input ${{ runner.temp }}/iriswebapp_nginx.tar
131-
docker load --input ${{ runner.temp }}/iriswebapp_app.tar
132-
- name: Check out iris
133-
uses: actions/checkout@v4
134-
- name: Start development server
135-
run: |
136-
cp .env.tests.model .env
137-
docker compose --file docker-compose.dev.yml up --detach --wait
138-
- name: Generate GraphQL documentation
139-
run: |
140-
npx spectaql@^3.0.2 source/spectaql/config.yml
141-
- name: Stop development server
142-
run: |
143-
docker compose down
144-
- uses: actions/upload-artifact@v4
145-
with:
146-
name: GraphQL DFIR-IRIS documentation
147-
path: public
148-
if-no-files-found: error
149-
150113
test-api:
151114
name: Test API
152115
runs-on: ubuntu-22.04

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,7 @@ run_nv_test.py
3131
certificates/web_certificates/*.pem
3232
certificates/web_certificates/*.key
3333
!certificates/web_certificates/iris_dev_*
34-
local_dev/
34+
local_dev/
35+
.serena/
36+
.tokensave
37+
.claude/

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ The upstream project is a DFIR case-management platform (Python/Flask backend, S
1010
| Branch | Purpose | Push rules |
1111
|---|---|---|
1212
| `bv-main` | Production-stable. Tagged releases deploy to AKS prod. | PR only, 1 approval + CI green |
13-
| `bv-develop` | Integration branch. Pushes auto-deploy to AKS staging. | Direct push allowed; PR preferred |
13+
| `bv-develop` | Integration branch. Staging (AKS) deploy is triggered manually, not automatically on push. | Direct push allowed; PR preferred |
1414
| `origin/master` | Upstream master mirror — **never modify** | Read-only |
1515
| `origin/develop` | Upstream develop mirror — **never modify** | Read-only |
1616

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<p align="center">
77
Incident Response Investigation System
88
<br>
9-
<i>Current Version v2.5.0-bv1</i>
9+
<i>Current Version v2.5.0-bv2</i>
1010
<br>
1111
<a href="https://v200.beta.dfir-iris.org">Online Demonstration</a>
1212
</p>
@@ -56,7 +56,7 @@ git clone https://github.com/dfir-iris/iris-web.git
5656
cd iris-web
5757

5858
# Checkout to the last tagged version
59-
git checkout v2.4.20
59+
git checkout v2.5.0-beta.1
6060
# Copy the environment file
6161
cp .env.model .env
6262

bV-development-guide.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ upstream/develop ────────────────────
2222
2323
│ PR from release/ branch only
2424
25-
bv-develop ◄── integration branch → AKS staging
25+
bv-develop ◄── integration branch → AKS staging (manual deploy trigger)
2626
2727
┌────┴────────────────────┐
2828
▼ ▼
@@ -37,7 +37,7 @@ sync/upstream-<date> → PR to bv-develop (short-lived, delet
3737
| Branch | Purpose | Azure DevOps trigger |
3838
|---|---|---|
3939
| `bv-main` | Production-stable, tagged releases | Tag `v*-bv*` → deploy AKS prod (manual approval) |
40-
| `bv-develop` | Integration, always deployable | Push → deploy AKS staging (auto) |
40+
| `bv-develop` | Integration, always deployable | Push → deploy AKS staging (manual trigger) |
4141
| `origin/master` | Upstream master mirror — do not modify | None |
4242
| `origin/develop` | Upstream develop mirror — do not modify | None |
4343

@@ -160,7 +160,8 @@ Rule: **if a commit has no `[BV]` prefix, it must be clean enough to open a PR o
160160
| Trigger | Jobs | Gate |
161161
|---|---|---|
162162
| PR to `bv-develop` | Build, static checks, unit tests | Auto — must pass before merge |
163-
| Push to `bv-develop` | Build, push to ACR (`:develop` tag), deploy AKS staging | Auto |
163+
| Push to `bv-develop` | Build, push to ACR (`:develop` tag) | Auto |
164+
| Deploy AKS staging | Deploy latest `:develop` image | Manual trigger |
164165
| Tag `v*-bv*` | Build, push to ACR (`:version` + `:latest` tags), deploy AKS prod | Manual approval |
165166

166167
### Docker image naming in ACR

bV-local-dev-environment-setup.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,31 @@ podman compose -f docker-compose.bv.yml -p iris-bv logs -f bv-iriswebapp-app
6868

6969
---
7070

71+
## Running the test suite
72+
73+
`tests/*.py` talk to the app container directly on `127.0.0.1:8000` (see `API_URL` in
74+
`tests/iris.py`), so run the stack under its own project name (`iris-test`) and only start the
75+
services the tests need — no nginx, no frontend. Never point this project name at a real dev
76+
stack; treat its volumes as throwaway.
77+
78+
Don't run this alongside a real dev stack (`iris-bv`, `iris-web-bv`, ...) — they'd collide on the
79+
same host ports (8000/5432).
80+
81+
```bash
82+
# Build and start a disposable test stack (no nginx/worker needed to exercise the REST API)
83+
podman compose -f docker-compose.dev.yml -p iris-test up -d --build db rabbitmq app worker
84+
85+
# Wait for the app container to become healthy, then run the suite from the host
86+
# (test files are named tests_*.py, not pytest's default test_*.py pattern)
87+
cd tests
88+
python -m unittest discover -p 'tests_*.py' -v
89+
90+
# Tear down completely when done — safe to delete, this project only ever holds test fixtures
91+
podman compose -f docker-compose.dev.yml -p iris-test down -v
92+
```
93+
94+
---
95+
7196
## Working on UI (JavaScript/Svelte) changes
7297

7398
The `ui/dist` folder is bind-mounted into the container at `/iriswebapp/static`, so you can

deploy/kubernetes/charts/templates/ingress_route.yaml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,22 @@ spec:
1717
routes:
1818
{{- range $host := .Values.ingress.hosts }}
1919
{{- range $path := $host.paths }}
20+
{{- $svcName := $.Values.irisapp.name }}
21+
{{- $svcPort := $.Values.irisapp.service.port }}
22+
{{- if hasKey $path "serviceName" }}
23+
{{- $svcName = $path.serviceName }}
24+
{{- if hasKey $path "servicePort" }}
25+
{{- $svcPort = $path.servicePort }}
26+
{{- end }}
27+
{{- else if hasKey $path "servicePort" }}
28+
{{- $svcPort = $path.servicePort }}
29+
{{- end }}
2030
- kind: Rule
2131
match: >
2232
Host(`{{ $host.host }}`) && PathPrefix(`{{ $path.path }}`)
2333
services:
24-
- name: {{ $.Values.irisapp.name }}
25-
port: {{ $.Values.irisapp.service.port }}
34+
- name: {{ $svcName }}
35+
port: {{ $svcPort }}
2636
{{- end }}
2737
{{- end }}
2838
{{- end }}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
{{- if .Values.iriscollab.enabled }}
2+
---
3+
apiVersion: v1
4+
kind: PersistentVolumeClaim
5+
metadata:
6+
name: {{ .Values.iriscollab.name }}-pvc
7+
annotations:
8+
helm.sh/resource-policy: keep
9+
spec:
10+
accessModes:
11+
- ReadWriteOnce
12+
resources:
13+
requests:
14+
storage: {{ .Values.iriscollab.pvcSize }}
15+
---
16+
apiVersion: apps/v1
17+
kind: Deployment
18+
metadata:
19+
name: {{ .Values.iriscollab.name }}
20+
spec:
21+
replicas: {{ .Values.iriscollab.replicaCount }}
22+
selector:
23+
matchLabels:
24+
app: {{ .Values.iriscollab.app }}
25+
template:
26+
metadata:
27+
labels:
28+
app: {{ .Values.iriscollab.app }}
29+
spec:
30+
securityContext:
31+
{{- toYaml .Values.iriscollab.podSecurityContext | nindent 8 }}
32+
containers:
33+
- name: {{ .Values.iriscollab.name }}
34+
securityContext:
35+
{{- toYaml .Values.iriscollab.securityContext | nindent 12 }}
36+
resources:
37+
{{- toYaml .Values.iriscollab.resources | nindent 12 }}
38+
image: "{{ .Values.iriscollab.image }}:{{ .Values.iriscollab.tag }}"
39+
imagePullPolicy: "{{ .Values.iriscollab.imagePullPolicy }}"
40+
command: ['uvicorn', 'app.collab_server:app', '--host', '0.0.0.0', '--port', '5001']
41+
42+
env:
43+
{{- range $key := list "POSTGRES_USER" "POSTGRES_PASSWORD" "POSTGRES_ADMIN_USER" "POSTGRES_ADMIN_PASSWORD" "POSTGRES_PORT" "POSTGRES_SERVER" "IRIS_SECRET_KEY" "IRIS_SECURITY_PASSWORD_SALT" }}
44+
- name: {{ $key }}
45+
{{- if and (hasKey $.Values.iriscollab "envFromSecret") (has $key $.Values.iriscollab.envFromSecret.keys) }}
46+
valueFrom:
47+
secretKeyRef:
48+
name: {{ $.Values.iriscollab.envFromSecret.name }}
49+
key: {{ $key }}
50+
{{- else }}
51+
value: {{ index $.Values.iriscollab $key | quote }}
52+
{{- end }}
53+
{{- end }}
54+
55+
- name: IRIS_COLLAB_STORE_PATH
56+
value: /home/iris/server_data/collab
57+
58+
ports:
59+
- containerPort: 5001
60+
61+
readinessProbe:
62+
httpGet:
63+
path: /collab/healthz
64+
port: 5001
65+
initialDelaySeconds: 5
66+
periodSeconds: 10
67+
68+
livenessProbe:
69+
httpGet:
70+
path: /collab/healthz
71+
port: 5001
72+
initialDelaySeconds: 15
73+
periodSeconds: 30
74+
75+
volumeMounts:
76+
- mountPath: /home/iris/server_data/collab
77+
name: collab-data
78+
79+
volumes:
80+
- name: collab-data
81+
persistentVolumeClaim:
82+
claimName: {{ .Values.iriscollab.name }}-pvc
83+
---
84+
apiVersion: v1
85+
kind: Service
86+
metadata:
87+
name: {{ .Values.iriscollab.name }}
88+
labels:
89+
app: {{ .Values.iriscollab.app }}
90+
spec:
91+
type: ClusterIP
92+
ports:
93+
- port: 5001
94+
targetPort: 5001
95+
selector:
96+
app: {{ .Values.iriscollab.app }}
97+
{{- if .Values.iriscollab.ingress.enabled }}
98+
{{- if .Values.ingress.traefik.enabled }}
99+
---
100+
apiVersion: traefik.io/v1alpha1
101+
kind: IngressRoute
102+
metadata:
103+
name: {{ .Values.iriscollab.name }}-ingress-route
104+
spec:
105+
entryPoints:
106+
- {{ .Values.ingress.traefik.entryPoint | default "web" }}
107+
routes:
108+
{{- range $host := .Values.ingress.hosts }}
109+
- kind: Rule
110+
match: >
111+
Host(`{{ $host.host }}`) && PathPrefix(`/collab`)
112+
services:
113+
- name: {{ $.Values.iriscollab.name }}
114+
port: 5001
115+
{{- end }}
116+
{{- else }}
117+
---
118+
apiVersion: networking.k8s.io/v1
119+
kind: Ingress
120+
metadata:
121+
name: {{ .Values.iriscollab.name }}-ingress
122+
annotations:
123+
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
124+
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
125+
{{- with .Values.iriscollab.ingress.customAnnotations }}
126+
{{- toYaml . | nindent 4 }}
127+
{{- end }}
128+
spec:
129+
ingressClassName: {{ .Values.ingress.className }}
130+
rules:
131+
{{- range $host := .Values.ingress.hosts }}
132+
- host: {{ $host.host }}
133+
http:
134+
paths:
135+
- path: /collab
136+
pathType: Prefix
137+
backend:
138+
service:
139+
name: {{ $.Values.iriscollab.name }}
140+
port:
141+
number: 5001
142+
{{- end }}
143+
{{- if and .Values.ingress.enableTls (gt (len .Values.ingress.tls.hosts) 0) }}
144+
tls:
145+
- hosts:
146+
{{- range .Values.ingress.tls.hosts }}
147+
- {{ . }}
148+
{{- end }}
149+
secretName: {{ .Values.ingress.tls.secretName }}
150+
{{- end }}
151+
{{- end }}
152+
{{- end }}
153+
{{- end }}

0 commit comments

Comments
 (0)