feat: Implement air-gap functionality with timeline impact and evidence snapshot services
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled

- Added AirgapTimelineImpact, AirgapTimelineImpactInput, and AirgapTimelineImpactResult records for managing air-gap bundle import impacts.
- Introduced EvidenceSnapshotRecord, EvidenceSnapshotLinkInput, and EvidenceSnapshotLinkResult records for linking findings to evidence snapshots.
- Created IEvidenceSnapshotRepository interface for managing evidence snapshot records.
- Developed StalenessValidationService to validate staleness and enforce freshness thresholds.
- Implemented AirgapTimelineService for emitting timeline events related to bundle imports.
- Added EvidenceSnapshotService for linking findings to evidence snapshots and verifying their validity.
- Introduced AirGapOptions for configuring air-gap staleness enforcement and thresholds.
- Added minimal jsPDF stub for offline/testing builds in the web application.
- Created TypeScript definitions for jsPDF to enhance type safety in the web application.
This commit is contained in:
StellaOps Bot
2025-12-06 01:30:08 +02:00
parent 6c1177a6ce
commit 2eaf0f699b
144 changed files with 7578 additions and 2581 deletions

View File

@@ -19,18 +19,30 @@ spec:
selector:
matchLabels:
{{- include "stellaops.selectorLabels" (dict "root" $root "name" $name "svc" $svc) | nindent 6 }}
template:
metadata:
labels:
{{- include "stellaops.selectorLabels" (dict "root" $root "name" $name "svc" $svc) | nindent 8 }}
annotations:
stellaops.release/version: {{ $root.Values.global.release.version | quote }}
stellaops.release/channel: {{ $root.Values.global.release.channel | quote }}
spec:
containers:
- name: {{ $name }}
image: {{ $svc.image | quote }}
imagePullPolicy: {{ default $root.Values.global.image.pullPolicy $svc.imagePullPolicy }}
template:
metadata:
labels:
{{- include "stellaops.selectorLabels" (dict "root" $root "name" $name "svc" $svc) | nindent 8 }}
{{- if $svc.podAnnotations }}
annotations:
{{ toYaml $svc.podAnnotations | nindent 8 }}
{{- end }}
annotations:
stellaops.release/version: {{ $root.Values.global.release.version | quote }}
stellaops.release/channel: {{ $root.Values.global.release.channel | quote }}
spec:
{{- if $svc.podSecurityContext }}
securityContext:
{{ toYaml $svc.podSecurityContext | nindent 6 }}
{{- end }}
containers:
- name: {{ $name }}
image: {{ $svc.image | quote }}
imagePullPolicy: {{ default $root.Values.global.image.pullPolicy $svc.imagePullPolicy }}
{{- if $svc.securityContext }}
securityContext:
{{ toYaml $svc.securityContext | nindent 12 }}
{{- end }}
{{- if $svc.command }}
command:
{{- range $cmd := $svc.command }}
@@ -81,10 +93,18 @@ spec:
containerPort: {{ default (index $svcService "port") (index $svcService "targetPort") }}
protocol: {{ default "TCP" (index $svcService "protocol") }}
{{- end }}
{{- if $svc.resources }}
resources:
{{ toYaml $svc.resources | nindent 12 }}
{{- end }}
{{- if $svc.resources }}
resources:
{{ toYaml $svc.resources | nindent 12 }}
{{- end }}
{{- if $svc.securityContext }}
securityContext:
{{ toYaml $svc.securityContext | nindent 12 }}
{{- end }}
{{- if $svc.securityContext }}
securityContext:
{{ toYaml $svc.securityContext | nindent 12 }}
{{- end }}
{{- if $svc.livenessProbe }}
livenessProbe:
{{ toYaml $svc.livenessProbe | nindent 12 }}
@@ -148,13 +168,32 @@ spec:
affinity:
{{ toYaml $svc.affinity | nindent 8 }}
{{- end }}
{{- if $svc.tolerations }}
tolerations:
{{ toYaml $svc.tolerations | nindent 8 }}
{{- end }}
---
{{- if $svc.service }}
apiVersion: v1
{{- if $svc.tolerations }}
tolerations:
{{ toYaml $svc.tolerations | nindent 8 }}
{{- end }}
{{- if $svc.pdb }}
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ include "stellaops.fullname" (dict "root" $root "name" $name) }}
labels:
{{- include "stellaops.labels" (dict "root" $root "name" $name "svc" $svc) | nindent 4 }}
spec:
{{- if $svc.pdb.minAvailable }}
minAvailable: {{ $svc.pdb.minAvailable }}
{{- end }}
{{- if $svc.pdb.maxUnavailable }}
maxUnavailable: {{ $svc.pdb.maxUnavailable }}
{{- end }}
selector:
matchLabels:
{{- include "stellaops.selectorLabels" (dict "root" $root "name" $name "svc" $svc) | nindent 6 }}
{{- end }}
---
{{- if $svc.service }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "stellaops.fullname" (dict "root" $root "name" $name) }}

View File

@@ -0,0 +1,28 @@
{{- if and .Values.externalSecrets.enabled .Values.externalSecrets.secrets }}
{{- range $secret := .Values.externalSecrets.secrets }}
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: {{ include "stellaops.fullname" $ }}-{{ $secret.name }}
labels:
{{- include "stellaops.labels" $ | nindent 4 }}
spec:
refreshInterval: {{ default "1h" $secret.refreshInterval }}
secretStoreRef:
name: {{ $secret.storeRef.name }}
kind: {{ default "ClusterSecretStore" $secret.storeRef.kind }}
target:
name: {{ $secret.target.name | default (printf "%s-%s" (include "stellaops.fullname" $) $secret.name) }}
creationPolicy: {{ default "Owner" $secret.target.creationPolicy }}
data:
{{- range $secret.data }}
- secretKey: {{ .key }}
remoteRef:
key: {{ .remoteKey }}
{{- if .property }}
property: {{ .property }}
{{- end }}
{{- end }}
---
{{- end }}
{{- end }}

View File

@@ -0,0 +1,32 @@
{{- if and .Values.ingress.enabled .Values.ingress.hosts }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "stellaops.fullname" . }}
labels:
{{- include "stellaops.labels" . | nindent 4 }}
annotations:
{{- range $k, $v := .Values.ingress.annotations }}
{{ $k }}: {{ $v | quote }}
{{- end }}
spec:
ingressClassName: {{ .Values.ingress.className | default "nginx" | quote }}
tls:
{{- range .Values.ingress.tls }}
- hosts: {{ toYaml .hosts | nindent 6 }}
secretName: {{ .secretName }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host }}
http:
paths:
- path: {{ .path | default "/" }}
pathType: Prefix
backend:
service:
name: {{ include "stellaops.fullname" $ }}-gateway
port:
number: {{ .servicePort | default 80 }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,50 @@
{{- if and .Values.migrations.enabled .Values.migrations.jobs }}
{{- range $job := .Values.migrations.jobs }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "stellaops.fullname" $ }}-migration-{{ $job.name | trunc 30 | trimSuffix "-" }}
labels:
{{- include "stellaops.labels" $ | nindent 4 }}
stellaops.io/component: migration
stellaops.io/migration-name: {{ $job.name | quote }}
spec:
backoffLimit: {{ default 3 $job.backoffLimit }}
ttlSecondsAfterFinished: {{ default 3600 $job.ttlSecondsAfterFinished }}
template:
metadata:
labels:
{{- include "stellaops.selectorLabels" $ | nindent 8 }}
stellaops.io/component: migration
stellaops.io/migration-name: {{ $job.name | quote }}
spec:
restartPolicy: {{ default "Never" $job.restartPolicy }}
serviceAccountName: {{ default "default" $job.serviceAccountName }}
containers:
- name: {{ $job.name | trunc 50 | trimSuffix "-" }}
image: {{ $job.image | quote }}
imagePullPolicy: {{ default "IfNotPresent" $job.imagePullPolicy }}
command: {{- if $job.command }} {{ toJson $job.command }} {{- else }} null {{- end }}
args: {{- if $job.args }} {{ toJson $job.args }} {{- else }} null {{- end }}
env:
{{- if $job.env }}
{{- range $k, $v := $job.env }}
- name: {{ $k }}
value: {{ $v | quote }}
{{- end }}
{{- end }}
envFrom:
{{- if $job.envFrom }}
{{- toYaml $job.envFrom | nindent 12 }}
{{- end }}
resources:
{{- if $job.resources }}
{{- toYaml $job.resources | nindent 12 }}
{{- else }}{}
{{- end }}
imagePullSecrets:
{{- if $.Values.global.image.pullSecrets }}
{{- toYaml $.Values.global.image.pullSecrets | nindent 8 }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,45 @@
{{- if .Values.networkPolicy.enabled }}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ include "stellaops.fullname" . }}-default
labels:
{{- include "stellaops.labels" . | nindent 4 }}
spec:
podSelector:
matchLabels:
{{- include "stellaops.selectorLabelsRoot" . | nindent 6 }}
policyTypes:
- Ingress
- Egress
ingress:
- from:
{{- if .Values.networkPolicy.ingressNamespaces }}
- namespaceSelector:
matchLabels:
{{- toYaml .Values.networkPolicy.ingressNamespaces | nindent 14 }}
{{- end }}
{{- if .Values.networkPolicy.ingressPods }}
- podSelector:
matchLabels:
{{- toYaml .Values.networkPolicy.ingressPods | nindent 14 }}
{{- end }}
ports:
- protocol: TCP
port: {{ default 80 .Values.networkPolicy.ingressPort }}
egress:
- to:
{{- if .Values.networkPolicy.egressNamespaces }}
- namespaceSelector:
matchLabels:
{{- toYaml .Values.networkPolicy.egressNamespaces | nindent 14 }}
{{- end }}
{{- if .Values.networkPolicy.egressPods }}
- podSelector:
matchLabels:
{{- toYaml .Values.networkPolicy.egressPods | nindent 14 }}
{{- end }}
ports:
- protocol: TCP
port: {{ default 443 .Values.networkPolicy.egressPort }}
{{- end }}