Skip to content
Merged
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ __pycache__/
.cursorrules
.cursor/
.vscode/
.venv/
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ These components are commented out in `values-hub.yaml` by default. Uncomment th
* [Red Hat Quay](https://docs.redhat.com/en/documentation/red_hat_quay) _(externalized chart)_
* Enables a private OCI image registry within the environment
* [Multicloud Object Gateway (NooBaa MCG)](https://docs.redhat.com/en/documentation/red_hat_openshift_data_foundation/latest/html/managing_hybrid_and_multicloud_resources/about-the-multicloud-object-gateway)
* Provides S3-compatible object storage for Quay and RHTPA
* Provides S3-compatible object storage for Quay, RHTPA, and Network Observability
* [Network Observability](https://docs.redhat.com/en/documentation/openshift_container_platform/latest/html/network_observability)
* eBPF flow collection and console Network Traffic views; requires storage/NooBaa
* [Red Hat Trusted Artifact Signer (RHTAS)](https://docs.redhat.com/en/documentation/red_hat_trusted_artifact_signer/1.3)
* Provides cryptographic signing and verification of software artifacts and container images
* [Red Hat Trusted Profile Analyzer (RHTPA)](https://docs.redhat.com/en/documentation/red_hat_trusted_profile_analyzer)
Expand Down
14 changes: 14 additions & 0 deletions charts/netobserv/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: v2
name: netobserv
description: OpenShift Network Observability (NooBaa-backed LokiStack + FlowCollector) for ZTVP
type: application
version: 0.1.0
appVersion: "1.12"
keywords:
- network-observability
- zero-trust
maintainers:
- name: Validated Patterns Team
home: https://validatedpatterns.io/patterns/layered-zero-trust/
sources:
- https://github.com/validatedpatterns/layered-zero-trust
26 changes: 26 additions & 0 deletions charts/netobserv/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{- define "netobserv.name" -}}
netobserv
{{- end }}

{{- define "netobserv.labels" -}}
app.kubernetes.io/name: {{ include "netobserv.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Resolve LokiStack storageClassName (required by the LokiStack CRD).

Use .Values.loki.storageClassName when set; otherwise fail. No Helm lookup —
Argo CD does not support it. Set explicitly via chart values, --set, or an
Argo CD / clusterGroup helm parameter override (see values.yaml comments and
scripts/features/netobserv.yaml). Discover classes with: oc get storageclass
*/}}
{{- define "netobserv.lokiStorageClassName" -}}
{{- $sc := .Values.loki.storageClassName | default "" -}}
{{- if $sc -}}
{{- $sc -}}
{{- else -}}
{{- fail "loki.storageClassName is required (LokiStack CRD). Set it in chart values (loki.storageClassName), via --set, or as an Argo CD / clusterGroup helm parameter override. See charts/netobserv/values.yaml. Discover classes: oc get storageclass" -}}
{{- end -}}
{{- end }}
35 changes: 35 additions & 0 deletions charts/netobserv/templates/flowcollector.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{{- if .Values.enabled }}
apiVersion: flows.netobserv.io/v1beta2
kind: FlowCollector
metadata:
name: {{ .Values.flowcollector.name }}
labels:
{{- include "netobserv.labels" . | nindent 4 }}
annotations:
argocd.argoproj.io/sync-wave: "42"
argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true
spec:
namespace: {{ .Values.flowcollector.namespace }}
deploymentModel: {{ .Values.flowcollector.deploymentModel }}
agent:
type: {{ .Values.flowcollector.agent.type }}
ebpf:
sampling: {{ .Values.flowcollector.agent.sampling }}
{{- if eq (.Values.flowcollector.agent.privileged | toString) "true" }}
privileged: true
{{- end }}
loki:
enable: {{ .Values.flowcollector.loki.enable }}
mode: {{ .Values.flowcollector.loki.mode }}
lokiStack:
name: {{ .Values.loki.name }}
namespace: {{ .Values.loki.namespace }}
consolePlugin:
enable: {{ .Values.flowcollector.consolePlugin.enable }}
{{- if eq (.Values.networkPolicy.enabled | toString) "true" }}
# Operator-managed NPs for netobserv + netobserv-privileged (not LokiStack ns).
networkPolicy:
enable: true
{{- end }}
{{- end }}

161 changes: 161 additions & 0 deletions charts/netobserv/templates/loki-s3-credentials-job.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
{{- if and .Values.enabled .Values.loki.enabled }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: netobserv-loki-s3-setup
namespace: {{ .Values.loki.namespace }}
labels:
{{- include "netobserv.labels" . | nindent 4 }}
annotations:
argocd.argoproj.io/sync-wave: "37"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: netobserv-loki-s3-setup
namespace: {{ .Values.loki.namespace }}
labels:
{{- include "netobserv.labels" . | nindent 4 }}
annotations:
argocd.argoproj.io/sync-wave: "37"
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "create", "update", "patch"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"]
- apiGroups: ["objectbucket.io"]
resources: ["objectbucketclaims"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: netobserv-loki-s3-setup
namespace: {{ .Values.loki.namespace }}
labels:
{{- include "netobserv.labels" . | nindent 4 }}
annotations:
argocd.argoproj.io/sync-wave: "37"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: netobserv-loki-s3-setup
subjects:
- kind: ServiceAccount
name: netobserv-loki-s3-setup
namespace: {{ .Values.loki.namespace }}
---
apiVersion: batch/v1
kind: Job
metadata:
name: netobserv-loki-s3-credentials
namespace: {{ .Values.loki.namespace }}
labels:
{{- include "netobserv.labels" . | nindent 4 }}
annotations:
argocd.argoproj.io/sync-wave: "39"
argocd.argoproj.io/hook: Sync
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
spec:
ttlSecondsAfterFinished: 600
backoffLimit: {{ .Values.credentialsJob.backoffLimit }}
template:
metadata:
labels:
{{- include "netobserv.labels" . | nindent 8 }}
spec:
serviceAccountName: netobserv-loki-s3-setup
automountServiceAccountToken: true
restartPolicy: OnFailure
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: remap-obc-secret
image: {{ .Values.credentialsJob.image }}
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
{{- toYaml .Values.credentialsJob.resources | nindent 12 }}
volumeMounts:
- name: tmp
mountPath: /tmp
env:
- name: NS
value: {{ .Values.loki.namespace | quote }}
- name: OBC_NAME
value: {{ .Values.loki.objectBucketClaim.name | quote }}
- name: LOKI_SECRET
value: {{ .Values.loki.storageSecretName | quote }}
- name: REGION
value: {{ .Values.loki.region | quote }}
command:
- /bin/bash
- -ec
- |
# NooBaa OBC creates a Secret (keys) + ConfigMap (bucket/host/port)
# with the same name as the claim — not all keys live in the Secret.
echo "Checking ObjectBucketClaim ${OBC_NAME} in ${NS}..."
oc get objectbucketclaim "${OBC_NAME}" -n "${NS}"

echo "Waiting for ObjectBucketClaim ${OBC_NAME} to be Bound (timeout: 10 minutes)..."
oc wait --for=jsonpath='{.status.phase}'=Bound \
"objectbucketclaim/${OBC_NAME}" -n "${NS}" --timeout=600s || {
echo "ERROR: ObjectBucketClaim failed to reach Bound state within timeout" >&2
oc describe objectbucketclaim "${OBC_NAME}" -n "${NS}" >&2 || true
exit 1
}

echo "Waiting for OBC Secret and ConfigMap ${OBC_NAME}..."
found=0
for i in $(seq 1 60); do
Comment thread
mlorenzofr marked this conversation as resolved.
if oc get secret "${OBC_NAME}" -n "${NS}" >/dev/null 2>&1 \
&& oc get configmap "${OBC_NAME}" -n "${NS}" >/dev/null 2>&1; then
found=1
break
fi
sleep 5
done
if [[ "${found}" -ne 1 ]]; then
echo "ERROR: OBC Secret and/or ConfigMap ${OBC_NAME} not available after 5 minutes" >&2
oc describe objectbucketclaim "${OBC_NAME}" -n "${NS}" >&2 || true
exit 1
fi

ACCESS=$(oc get secret "${OBC_NAME}" -n "${NS}" -o jsonpath='{.data.AWS_ACCESS_KEY_ID}' | base64 -d)
SECRET=$(oc get secret "${OBC_NAME}" -n "${NS}" -o jsonpath='{.data.AWS_SECRET_ACCESS_KEY}' | base64 -d)
BUCKET=$(oc get configmap "${OBC_NAME}" -n "${NS}" -o jsonpath='{.data.BUCKET_NAME}')
HOST=$(oc get configmap "${OBC_NAME}" -n "${NS}" -o jsonpath='{.data.BUCKET_HOST}')
PORT=$(oc get configmap "${OBC_NAME}" -n "${NS}" -o jsonpath='{.data.BUCKET_PORT}')

if [[ -z "${ACCESS}" || -z "${SECRET}" || -z "${BUCKET}" || -z "${HOST}" ]]; then
echo "OBC Secret/ConfigMap is missing required keys" >&2
exit 1
fi

if [[ -n "${PORT}" && "${PORT}" != "443" ]]; then
ENDPOINT="https://${HOST}:${PORT}"
else
ENDPOINT="https://${HOST}"
fi

oc create secret generic "${LOKI_SECRET}" -n "${NS}" \
--from-literal=access_key_id="${ACCESS}" \
--from-literal=access_key_secret="${SECRET}" \
--from-literal=bucketnames="${BUCKET}" \
--from-literal=endpoint="${ENDPOINT}" \
--from-literal=region="${REGION}" \
--dry-run=client -o yaml | oc apply -f -
echo "Created/updated ${LOKI_SECRET} for LokiStack (endpoint=${ENDPOINT})"
volumes:
- name: tmp
emptyDir: {}
{{- end }}
24 changes: 24 additions & 0 deletions charts/netobserv/templates/lokistack.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{{- if and .Values.enabled .Values.loki.enabled }}
apiVersion: loki.grafana.com/v1
kind: LokiStack
metadata:
name: {{ .Values.loki.name }}
namespace: {{ .Values.loki.namespace }}
labels:
{{- include "netobserv.labels" . | nindent 4 }}
annotations:
argocd.argoproj.io/sync-wave: "41"
argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true
spec:
size: {{ .Values.loki.size }}
storage:
schemas:
- version: v13
effectiveDate: "2022-06-01"
secret:
name: {{ .Values.loki.storageSecretName }}
type: s3
storageClassName: {{ include "netobserv.lokiStorageClassName" . }}
tenants:
mode: openshift-network
{{- end }}
Loading
Loading