{{ .Params.lead | safeHTML }}
+ Open The Docs + {{ .Content }} +Start your journey with DefectDojo with our New User Checklist.
+Learn how to import data from 190+ supported security tools here.
+Use the Report Builder to present customizable reports of Findings.
+Check out live events, upcoming features and connect with other security professionals on our Community Page.
+Ready to go Pro? Create an account here.
+Need some help? Pro users can send an email to support@defectdojo.com
++ {% trans "Hello" %}, +
++ {% blocktranslate trimmed with engagement_name=engagement.name engagement_product=engagement.product prod_url=product_url|full_url eng_url=engagement_url|full_url%} + The engagement "{{ engagement_name }}" has been closed in the product "{{ engagement_product }}". It can be viewed here: {{product}} / {{ engagement_name }} + {% endblocktranslate %} +
++ {% url 'notifications' as notification_url %} + {% trans "You can manage your notification settings here" %}: {{ notification_url|full_url }} +
+ {% if system_settings.disclaimer and system_settings.disclaimer.strip %} +{{ system_settings.disclaimer }}
+tags from HTML strings to avoid importing yet-another-library. + Args: html_string: The HMTL string to remove
tags from Returns: The original string stipped of paragraph tags + """ return re.sub(r"
|
", "", html_string) @@ -193,12 +203,13 @@ def _convert_whitehat_sentinel_vulns_to_dojo_finding( whitehat_sentinel_vulns: The vuln dictionary from WhiteHat Sentinel vuln API test: The test ID that the DefectDojo finding should be associated with Returns: A DefectDojo Finding object + """ dupes = {} for whitehat_vuln in whitehat_sentinel_vulns: date_created = whitehat_vuln["found"].split("T")[0] - mitigated_ts = whitehat_vuln.get("closed".split("T")[0], None) + mitigated_ts = whitehat_vuln.get("closed", None) if mitigated_ts is not None: mitigated_ts = datetime.strptime(mitigated_ts, "%Y-%m-%dT%H:%M:%SZ") cwe = self._parse_cwe_from_tags( diff --git a/dojo/tools/wpscan/parser.py b/dojo/tools/wpscan/parser.py index 95c0a8c4c20..2ba6b5016b7 100644 --- a/dojo/tools/wpscan/parser.py +++ b/dojo/tools/wpscan/parser.py @@ -1,6 +1,6 @@ +import datetime import hashlib import json -from datetime import datetime from dojo.models import Endpoint, Finding @@ -89,7 +89,7 @@ def get_findings(self, file, test): report_date = None if "start_time" in tree: - report_date = datetime.utcfromtimestamp(tree.get("start_time")) + report_date = datetime.datetime.fromtimestamp(tree.get("start_time"), datetime.UTC) dupes = {} # manage plugin findings diff --git a/dojo/tools/xanitizer/parser.py b/dojo/tools/xanitizer/parser.py index b6a7cabdd55..b4eca87b40f 100644 --- a/dojo/tools/xanitizer/parser.py +++ b/dojo/tools/xanitizer/parser.py @@ -85,15 +85,9 @@ def generate_title(self, finding, line): cl = finding.find("class") file = finding.find("file") if pckg is not None and cl is not None: - if line: - title = f"{title} ({pckg.text}.{cl.text}:{line})" - else: - title = f"{title} ({pckg.text}.{cl.text})" + title = f"{title} ({pckg.text}.{cl.text}:{line})" if line else f"{title} ({pckg.text}.{cl.text})" else: - if line: - title = f"{title} ({file.text}:{line})" - else: - title = f"{title} ({file.text})" + title = f"{title} ({file.text}:{line})" if line else f"{title} ({file.text})" return title diff --git a/dojo/user/views.py b/dojo/user/views.py index f43b6b7b600..0f8914e4adf 100644 --- a/dojo/user/views.py +++ b/dojo/user/views.py @@ -227,10 +227,7 @@ def view_profile(request): group_members = get_authorized_group_members_for_user(user) user_contact = user.usercontactinfo if hasattr(user, "usercontactinfo") else None - if user_contact is None: - contact_form = UserContactInfoForm() - else: - contact_form = UserContactInfoForm(instance=user_contact) + contact_form = UserContactInfoForm() if user_contact is None else UserContactInfoForm(instance=user_contact) global_role = user.global_role if hasattr(user, "global_role") else None if global_role is None: @@ -393,16 +390,10 @@ def edit_user(request, uid): form = EditDojoUserForm(instance=user) user_contact = user.usercontactinfo if hasattr(user, "usercontactinfo") else None - if user_contact is None: - contact_form = UserContactInfoForm() - else: - contact_form = UserContactInfoForm(instance=user_contact) + contact_form = UserContactInfoForm() if user_contact is None else UserContactInfoForm(instance=user_contact) global_role = user.global_role if hasattr(user, "global_role") else None - if global_role is None: - global_role_form = GlobalRoleForm() - else: - global_role_form = GlobalRoleForm(instance=global_role) + global_role_form = GlobalRoleForm() if global_role is None else GlobalRoleForm(instance=global_role) if request.method == "POST": form = EditDojoUserForm(request.POST, instance=user) diff --git a/dojo/utils.py b/dojo/utils.py index c57695c09d9..8c2df2be847 100644 --- a/dojo/utils.py +++ b/dojo/utils.py @@ -11,6 +11,7 @@ from collections.abc import Callable from datetime import date, datetime, timedelta from math import pi, sqrt +from pathlib import Path import bleach import crum @@ -88,6 +89,7 @@ def do_false_positive_history(finding, *args, **kwargs): Args: finding (:model:`dojo.Finding`): Finding to be replicated + """ to_mark_as_fp = set() @@ -149,6 +151,7 @@ def match_finding_to_existing_findings(finding, product=None, engagement=None, t product (:model:`dojo.Product`, optional): Product to filter findings by engagement (:model:`dojo.Engagement`, optional): Engagement to filter findings by test (:model:`dojo.Test`, optional): Test to filter findings by + """ if product: custom_filter_type = "product" @@ -781,11 +784,7 @@ def is_title_in_breadcrumbs(title): if breadcrumbs is None: return False - for breadcrumb in breadcrumbs: - if breadcrumb.get("title") == title: - return True - - return False + return any(breadcrumb.get("title") == title for breadcrumb in breadcrumbs) def get_punchcard_data(objs, start_date, weeks, view="Finding"): @@ -1327,15 +1326,9 @@ def build_query(query_string, search_fields): for field_name in search_fields: q = Q(**{f"{field_name}__icontains": term}) - if or_query: - or_query = or_query | q - else: - or_query = q + or_query = or_query | q if or_query else q - if query: - query = query & or_query - else: - query = or_query + query = query & or_query if query else or_query return query @@ -1378,11 +1371,12 @@ def get_page_items_and_count(request, items, page_size, prefix="", do_count=True def handle_uploaded_threat(f, eng): - _name, extension = os.path.splitext(f.name) + path = Path(f.name) + extension = path.suffix # Check if threat folder exist. - if not os.path.isdir(settings.MEDIA_ROOT + "/threat/"): + if not Path(settings.MEDIA_ROOT + "/threat/").is_dir(): # Create the folder - os.mkdir(settings.MEDIA_ROOT + "/threat/") + Path(settings.MEDIA_ROOT + "/threat/").mkdir() with open(settings.MEDIA_ROOT + f"/threat/{eng.id}{extension}", "wb+") as destination: for chunk in f.chunks(): @@ -1392,7 +1386,8 @@ def handle_uploaded_threat(f, eng): def handle_uploaded_selenium(f, cred): - _name, extension = os.path.splitext(f.name) + path = Path(f.name) + extension = path.suffix with open(settings.MEDIA_ROOT + f"/selenium/{cred.id}{extension}", "wb+") as destination: for chunk in f.chunks(): @@ -1848,7 +1843,7 @@ def get_return_url(request): return_url = request.POST.get("return_url", None) if return_url is None or not return_url.strip(): # for some reason using request.GET.get('return_url') never works - return_url = request.GET["return_url"] if "return_url" in request.GET else None + return_url = request.GET["return_url"] if "return_url" in request.GET else None # noqa: SIM401 return return_url or None @@ -2047,7 +2042,7 @@ def _create_notifications(): if sla_age is None: sla_age = 0 - if (sla_age < 0) and (settings.SLA_NOTIFY_POST_BREACH < abs(sla_age)): + if (sla_age < 0) and (abs(sla_age) > settings.SLA_NOTIFY_POST_BREACH): post_breach_no_notify_count += 1 # Skip finding notification if breached for too long logger.debug(f"Finding {finding.id} breached the SLA {abs(sla_age)} days ago. Skipping notifications.") @@ -2299,7 +2294,7 @@ def get_product(obj): if not obj: return None - if isinstance(obj, Finding) or isinstance(obj, Finding_Group): + if isinstance(obj, Finding | Finding_Group): return obj.test.engagement.product if isinstance(obj, Test): @@ -2696,7 +2691,9 @@ def generate_file_response_from_file_path( ) -> FileResponse: """Serve an local file in a uniformed way.""" # Determine the file path - file_path_without_extension, file_extension = os.path.splitext(file_path) + path = Path(file_path) + file_path_without_extension = path.parent / path.stem + file_extension = path.suffix # Determine the file name if not supplied if file_name is None: file_name = file_path_without_extension.rsplit("/")[-1] diff --git a/dojo/views.py b/dojo/views.py index ff0faed8c26..df65be4d6bd 100644 --- a/dojo/views.py +++ b/dojo/views.py @@ -1,5 +1,6 @@ import logging import os +from pathlib import Path from auditlog.models import LogEntry from django.conf import settings @@ -150,7 +151,7 @@ def manage_files(request, oid, obj_type): for o in files_formset.deleted_objects: logger.debug("removing file: %s", o.file.name) - os.remove(os.path.join(settings.MEDIA_ROOT, o.file.name)) + Path(os.path.join(settings.MEDIA_ROOT, o.file.name)).unlink() for o in files_formset.new_objects: logger.debug("adding file: %s", o.file.name) @@ -161,7 +162,7 @@ def manage_files(request, oid, obj_type): finding__isnull=True) for o in orphan_files: logger.debug("purging orphan file: %s", o.file.name) - os.remove(os.path.join(settings.MEDIA_ROOT, o.file.name)) + Path(os.path.join(settings.MEDIA_ROOT, o.file.name)).unlink() o.delete() messages.add_message( diff --git a/helm/defectdojo/.helmignore b/helm/defectdojo/.helmignore index 50af0317254..70909a86d60 100644 --- a/helm/defectdojo/.helmignore +++ b/helm/defectdojo/.helmignore @@ -20,3 +20,4 @@ .idea/ *.tmproj .vscode/ +README.md diff --git a/helm/defectdojo/Chart.lock b/helm/defectdojo/Chart.lock index 611d1100a44..7a0e49b95de 100644 --- a/helm/defectdojo/Chart.lock +++ b/helm/defectdojo/Chart.lock @@ -1,12 +1,12 @@ dependencies: - name: postgresql repository: https://charts.bitnami.com/bitnami - version: 16.1.0 + version: 16.2.0 - name: postgresql-ha repository: https://charts.bitnami.com/bitnami version: 9.4.11 - name: redis repository: https://charts.bitnami.com/bitnami version: 19.6.4 -digest: sha256:499d18e7070e7752e0dccfa2187d755570e105eb21cae37d6f0623a333997db8 -generated: "2024-10-30T17:58:45.866148081Z" +digest: sha256:0d2e729a1b07543cb813f80f5d05c67ad56817f1b44911e08245e43868f49301 +generated: "2024-11-14T10:51:48.400717864Z" diff --git a/helm/defectdojo/Chart.yaml b/helm/defectdojo/Chart.yaml index b61326d1b8d..9259be0a6c9 100644 --- a/helm/defectdojo/Chart.yaml +++ b/helm/defectdojo/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v2 -appVersion: "2.41.0-dev" +appVersion: "2.42.0-dev" description: A Helm chart for Kubernetes to install DefectDojo name: defectdojo -version: 1.6.159-dev +version: 1.6.163-dev icon: https://www.defectdojo.org/img/favicon.ico maintainers: - name: madchap @@ -10,7 +10,7 @@ maintainers: url: https://github.com/DefectDojo/django-DefectDojo dependencies: - name: postgresql - version: ~16.1.0 + version: ~16.2.0 repository: "https://charts.bitnami.com/bitnami" condition: postgresql.enabled - name: postgresql-ha diff --git a/helm/defectdojo/README.md b/helm/defectdojo/README.md new file mode 120000 index 00000000000..5c0dd98ed0f --- /dev/null +++ b/helm/defectdojo/README.md @@ -0,0 +1 @@ +../../readme-docs/KUBERNETES.md \ No newline at end of file diff --git a/helm/defectdojo/templates/_helpers.tpl b/helm/defectdojo/templates/_helpers.tpl index 14256e88190..c3e0026c2ef 100644 --- a/helm/defectdojo/templates/_helpers.tpl +++ b/helm/defectdojo/templates/_helpers.tpl @@ -102,8 +102,12 @@ Create chart name and version as used by the chart label. {{- end -}} {{- define "initializer.jobname" -}} +{{- if .Values.initializer.staticName -}} +{{ .Release.Name }}-initializer +{{- else -}} {{ .Release.Name }}-initializer-{{- printf "%s" now | date "2006-01-02-15-04" -}} {{- end -}} +{{- end -}} {{/* Creates the array for DD_ALLOWED_HOSTS in configmap diff --git a/helm/defectdojo/templates/celery-beat-deployment.yaml b/helm/defectdojo/templates/celery-beat-deployment.yaml index 7eda46b8680..aedbb117275 100644 --- a/helm/defectdojo/templates/celery-beat-deployment.yaml +++ b/helm/defectdojo/templates/celery-beat-deployment.yaml @@ -10,6 +10,9 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ include "defectdojo.chart" . }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} spec: replicas: {{ .Values.celery.beat.replicas }} {{- if .Values.revisionHistoryLimit }} @@ -28,8 +31,11 @@ spec: defectdojo.org/subcomponent: beat app.kubernetes.io/name: {{ include "defectdojo.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} - {{- if .Values.podLabels }} - {{- toYaml .Values.podLabels | nindent 8 }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} {{- end }} annotations: {{- with .Values.celery.beat.annotations }} @@ -66,17 +72,14 @@ spec: path: {{ .hostPath }} {{- end }} {{- end }} - {{- if .Values.dbMigrationChecker.enabled }} + {{- if or .Values.dbMigrationChecker.enabled .Values.cloudsql.enabled }} initContainers: - {{$data := dict "fullName" $fullName }} - {{- $newContext := merge . (dict "fullName" $fullName) }} - {{- include "dbMigrationChecker" $newContext | nindent 6 }} {{- end }} - containers: {{- if .Values.cloudsql.enabled }} - name: cloudsql-proxy image: {{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }} imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy }} + restartPolicy: Always securityContext: runAsNonRoot: true command: ["/cloud_sql_proxy"] @@ -92,6 +95,12 @@ spec: - "-ip_address_types=PRIVATE" {{- end }} {{- end }} + {{- if .Values.dbMigrationChecker.enabled }} + {{$data := dict "fullName" $fullName }} + {{- $newContext := merge . (dict "fullName" $fullName) }} + {{- include "dbMigrationChecker" $newContext | nindent 6 }} + {{- end }} + containers: - command: - /entrypoint-celery-beat.sh name: celery @@ -143,8 +152,8 @@ spec: secretKeyRef: name: {{ $fullName }} key: DD_SECRET_KEY - {{- if .Values.extraEnv }} - {{- toYaml .Values.extraEnv | nindent 8 }} + {{- with .Values.extraEnv }} + {{- toYaml . | nindent 8 }} {{- end }} resources: {{- toYaml .Values.celery.beat.resources | nindent 10 }} diff --git a/helm/defectdojo/templates/celery-worker-deployment.yaml b/helm/defectdojo/templates/celery-worker-deployment.yaml index f21be7a13be..c9505959bda 100644 --- a/helm/defectdojo/templates/celery-worker-deployment.yaml +++ b/helm/defectdojo/templates/celery-worker-deployment.yaml @@ -10,6 +10,9 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ include "defectdojo.chart" . }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} spec: replicas: {{ .Values.celery.worker.replicas }} {{- if .Values.revisionHistoryLimit }} @@ -28,8 +31,11 @@ spec: defectdojo.org/subcomponent: worker app.kubernetes.io/name: {{ include "defectdojo.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} - {{- if .Values.podLabels }} - {{- toYaml .Values.podLabels | nindent 8 }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} {{- end }} annotations: {{- with .Values.celery.worker.annotations }} @@ -64,17 +70,14 @@ spec: path: {{ .hostPath }} {{- end }} {{- end }} - {{- if .Values.dbMigrationChecker.enabled }} + {{- if or .Values.dbMigrationChecker.enabled .Values.cloudsql.enabled }} initContainers: - {{$data := dict "fullName" $fullName }} - {{- $newContext := merge . (dict "fullName" $fullName) }} - {{- include "dbMigrationChecker" $newContext | nindent 6 }} {{- end }} - containers: {{- if .Values.cloudsql.enabled }} - name: cloudsql-proxy image: {{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }} imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy }} + restartPolicy: Always securityContext: runAsNonRoot: true command: ["/cloud_sql_proxy"] @@ -90,6 +93,12 @@ spec: - "-ip_address_types=PRIVATE" {{- end }} {{- end }} + {{- if .Values.dbMigrationChecker.enabled }} + {{$data := dict "fullName" $fullName }} + {{- $newContext := merge . (dict "fullName" $fullName) }} + {{- include "dbMigrationChecker" $newContext | nindent 6 }} + {{- end }} + containers: - name: celery image: "{{ template "celery.repository" . }}:{{ .Values.tag }}" imagePullPolicy: {{ .Values.imagePullPolicy }} @@ -138,8 +147,8 @@ spec: secretKeyRef: name: {{ $fullName }} key: DD_SECRET_KEY - {{- if .Values.extraEnv }} - {{- toYaml .Values.extraEnv | nindent 8 }} + {{- with .Values.extraEnv }} + {{- toYaml . | nindent 8 }} {{- end }} resources: {{- toYaml .Values.celery.worker.resources | nindent 10 }} diff --git a/helm/defectdojo/templates/configmap.yaml b/helm/defectdojo/templates/configmap.yaml index 5ae741f0abc..0d8c4a238e1 100644 --- a/helm/defectdojo/templates/configmap.yaml +++ b/helm/defectdojo/templates/configmap.yaml @@ -8,6 +8,9 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ include "defectdojo.chart" . }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} data: DD_ADMIN_USER: {{ .Values.admin.user | default "admin" }} DD_ADMIN_MAIL: {{ .Values.admin.Mail | default "admin@defectdojo.local" }} @@ -45,5 +48,5 @@ data: {{- if .Values.django.uwsgi.certificates.enabled }} REQUESTS_CA_BUNDLE: {{ .Values.django.uwsgi.certificates.certMountPath }}{{ .Values.django.uwsgi.certificates.certFileName }} {{- end }} -{{- if .Values.extraConfigs }} -{{ toYaml .Values.extraConfigs | indent 2 }}{{- end }} +{{- with .Values.extraConfigs }} + {{- toYaml . | nindent 2 }}{{- end }} diff --git a/helm/defectdojo/templates/django-deployment.yaml b/helm/defectdojo/templates/django-deployment.yaml index ce126f1cc28..5ef3dec50cc 100644 --- a/helm/defectdojo/templates/django-deployment.yaml +++ b/helm/defectdojo/templates/django-deployment.yaml @@ -9,6 +9,9 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ include "defectdojo.chart" . }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} spec: replicas: {{ .Values.django.replicas }} {{- if .Values.revisionHistoryLimit }} @@ -25,9 +28,12 @@ spec: defectdojo.org/component: django app.kubernetes.io/name: {{ include "defectdojo.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} - {{- if .Values.podLabels }} - {{- toYaml .Values.podLabels | nindent 8 }} - {{- end }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} annotations: {{- with .Values.django.annotations }} {{- toYaml . | nindent 8 }} @@ -82,17 +88,14 @@ spec: emptyDir: {} {{- end }} {{- end }} - {{- if .Values.dbMigrationChecker.enabled }} + {{- if or .Values.dbMigrationChecker.enabled .Values.cloudsql.enabled }} initContainers: - {{$data := dict "fullName" $fullName }} - {{- $newContext := merge . (dict "fullName" $fullName) }} - {{- include "dbMigrationChecker" $newContext | nindent 6 }} {{- end }} - containers: {{- if .Values.cloudsql.enabled }} - name: cloudsql-proxy image: {{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }} imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy }} + restartPolicy: Always securityContext: runAsNonRoot: true command: ["/cloud_sql_proxy"] @@ -108,6 +111,12 @@ spec: - "-ip_address_types=PRIVATE" {{- end }} {{- end }} + {{- if .Values.dbMigrationChecker.enabled }} + {{$data := dict "fullName" $fullName }} + {{- $newContext := merge . (dict "fullName" $fullName) }} + {{- include "dbMigrationChecker" $newContext | nindent 6 }} + {{- end }} + containers: {{- if and .Values.monitoring.enabled .Values.monitoring.prometheus.enabled }} - name: metrics image: {{ .Values.monitoring.prometheus.image }} @@ -155,11 +164,6 @@ spec: - name: http-uwsgi protocol: TCP containerPort: 8081 - {{- if .Values.django.uwsgi.enableDebug }} - - name: debug - protocol: TCP - containerPort: 3000 - {{- end }} envFrom: - configMapRef: name: {{ $fullName }} @@ -202,8 +206,8 @@ spec: value: {{- if or .Values.django.ingress.activateTLS .Values.django.nginx.tls.enabled }} "True" {{- else }} "False" {{- end }} - name: DD_CSRF_COOKIE_SECURE value: {{- if or .Values.django.ingress.activateTLS .Values.django.nginx.tls.enabled }} "True" {{- else }} "False" {{- end }} - {{- if .Values.extraEnv }} - {{- toYaml .Values.extraEnv | nindent 8 }} + {{- with .Values.extraEnv }} + {{- toYaml . | nindent 8 }} {{- end }} {{- if .Values.django.uwsgi.livenessProbe.enabled }} livenessProbe: @@ -260,6 +264,7 @@ spec: value: '{{ .Values.django.nginx.tls.enabled }}' - name: GENERATE_TLS_CERTIFICATE value: '{{ .Values.django.nginx.tls.generateCertificate }}' + {{- if .Values.django.uwsgi.livenessProbe.enabled }} livenessProbe: httpGet: path: /nginx_health @@ -270,10 +275,13 @@ spec: httpHeaders: - name: Host value: {{ .Values.host }} - initialDelaySeconds: 10 - periodSeconds: 10 - failureThreshold: 6 - {{- if .Values.django.uwsgi.livenessProbe.enabled }} + failureThreshold: {{ .Values.django.uwsgi.livenessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.django.uwsgi.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.django.uwsgi.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.django.uwsgi.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.django.uwsgi.livenessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.django.uwsgi.readinessProbe.enabled }} readinessProbe: httpGet: path: /uwsgi_health @@ -284,11 +292,28 @@ spec: httpHeaders: - name: Host value: {{ .Values.host }} - failureThreshold: {{ .Values.django.uwsgi.livenessProbe.failureThreshold }} - initialDelaySeconds: {{ .Values.django.uwsgi.livenessProbe.initialDelaySeconds }} - periodSeconds: {{ .Values.django.uwsgi.livenessProbe.periodSeconds }} - successThreshold: {{ .Values.django.uwsgi.livenessProbe.successThreshold }} - timeoutSeconds: {{ .Values.django.uwsgi.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.django.uwsgi.readinessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.django.uwsgi.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.django.uwsgi.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.django.uwsgi.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.django.uwsgi.readinessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.django.uwsgi.startupProbe.enabled }} + startupProbe: + httpGet: + path: /uwsgi_health + port: http + {{- if .Values.django.nginx.tls.enabled }} + scheme: HTTPS + {{- end }} + httpHeaders: + - name: Host + value: {{ .Values.host }} + failureThreshold: {{ .Values.django.uwsgi.startupProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.django.uwsgi.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.django.uwsgi.startupProbe.periodSeconds }} + successThreshold: {{ .Values.django.uwsgi.startupProbe.successThreshold }} + timeoutSeconds: {{ .Values.django.uwsgi.startupProbe.timeoutSeconds }} {{- end }} resources: {{- toYaml .Values.django.nginx.resources | nindent 10 }} diff --git a/helm/defectdojo/templates/django-ingress.yaml b/helm/defectdojo/templates/django-ingress.yaml index 73ea41404b9..9beecdda923 100644 --- a/helm/defectdojo/templates/django-ingress.yaml +++ b/helm/defectdojo/templates/django-ingress.yaml @@ -14,10 +14,13 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ include "defectdojo.chart" . }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} {{- if or .Values.django.ingress.annotations .Values.gke.useGKEIngress }} annotations: {{- with .Values.django.ingress.annotations }} -{{ toYaml . | indent 4 }} + {{- toYaml . | nindent 4 }} {{- end }} {{- if .Values.gke.useGKEIngress }} kubernetes.io/ingress.class: gce diff --git a/helm/defectdojo/templates/django-service.yaml b/helm/defectdojo/templates/django-service.yaml index b64f3a05570..3823886bbd2 100644 --- a/helm/defectdojo/templates/django-service.yaml +++ b/helm/defectdojo/templates/django-service.yaml @@ -9,6 +9,9 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ include "defectdojo.chart" . }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} {{- if .Values.django.service.annotations }} annotations: {{- range $key, $value := .Values.django.service.annotations }} diff --git a/helm/defectdojo/templates/extra-secret.yaml b/helm/defectdojo/templates/extra-secret.yaml index a21e8e27ba6..21f9a9507ee 100644 --- a/helm/defectdojo/templates/extra-secret.yaml +++ b/helm/defectdojo/templates/extra-secret.yaml @@ -9,6 +9,9 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ include "defectdojo.chart" . }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} type: Opaque data: {{- range $key, $value := .Values.extraSecrets }} diff --git a/helm/defectdojo/templates/initializer-job.yaml b/helm/defectdojo/templates/initializer-job.yaml index b078a1fdc64..60d82b9f2d7 100644 --- a/helm/defectdojo/templates/initializer-job.yaml +++ b/helm/defectdojo/templates/initializer-job.yaml @@ -10,20 +10,28 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ include "defectdojo.chart" . }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} annotations: {{- with .Values.initializer.jobAnnotations }} {{- toYaml . | nindent 4 }} {{- end }} spec: + {{- if and (int .Values.initializer.keepSeconds) (gt (int .Values.initializer.keepSeconds) 0) }} ttlSecondsAfterFinished: {{ .Values.initializer.keepSeconds }} + {{- end }} template: metadata: labels: defectdojo.org/component: initializer app.kubernetes.io/name: {{ include "defectdojo.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} - {{- if .Values.initializer.labels }} - {{- toYaml .Values.initializer.labels | nindent 8 }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 8 }} + {{- end -}} + {{- with .Values.initializer.labels }} + {{- toYaml . | nindent 8 }} {{- end }} annotations: {{- with .Values.initializer.annotations }} @@ -49,28 +57,11 @@ spec: {{- end }} {{- end }} initContainers: - - name: wait-for-db - command: - - '/bin/bash' - - '-c' - - '/wait-for-it.sh ${DD_DATABASE_HOST:-postgres}:${DD_DATABASE_PORT:-5432} -t 300 -s -- /bin/echo Database is up' - image: '{{ template "django.uwsgi.repository" . }}:{{ .Values.tag }}' - imagePullPolicy: {{ .Values.imagePullPolicy }} - {{- if .Values.securityContext.enabled }} - securityContext: - {{- toYaml .Values.securityContext.djangoSecurityContext | nindent 10 }} - {{- end }} - envFrom: - - configMapRef: - name: {{ $fullName }} - - secretRef: - name: {{ $fullName }} - optional: true - containers: {{- if .Values.cloudsql.enabled }} - name: cloudsql-proxy image: {{ .Values.cloudsql.image.repository }}:{{ .Values.cloudsql.image.tag }} imagePullPolicy: {{ .Values.cloudsql.image.pullPolicy }} + restartPolicy: Always securityContext: runAsNonRoot: true command: ["/cloud_sql_proxy"] @@ -86,6 +77,28 @@ spec: - "-ip_address_types=PRIVATE" {{- end }} {{- end }} + - name: wait-for-db + command: + - '/bin/bash' + - '-c' + - '/wait-for-it.sh ${DD_DATABASE_HOST:-postgres}:${DD_DATABASE_PORT:-5432} -t 300 -s -- /bin/echo Database is up' + image: '{{ template "django.uwsgi.repository" . }}:{{ .Values.tag }}' + imagePullPolicy: {{ .Values.imagePullPolicy }} + {{- if .Values.securityContext.enabled }} + securityContext: + {{- toYaml .Values.securityContext.djangoSecurityContext | nindent 10 }} + {{- end }} + envFrom: + - configMapRef: + name: {{ $fullName }} + - secretRef: + name: {{ $fullName }} + optional: true + env: + {{- with .Values.extraEnv }} + {{- toYaml . | nindent 8 }} + {{- end }} + containers: - name: initializer image: "{{ template "initializer.repository" . }}:{{ .Values.tag }}" imagePullPolicy: {{ .Values.imagePullPolicy }} @@ -118,8 +131,8 @@ spec: name: {{ .Values.postgresqlha.postgresql.existingSecret }} key: postgresql-postgres-password {{- end }} - {{- if .Values.extraEnv }} - {{- toYaml .Values.extraEnv | nindent 8 }} + {{- with .Values.extraEnv }} + {{- toYaml . | nindent 8 }} {{- end }} resources: {{- toYaml .Values.initializer.resources | nindent 10 }} diff --git a/helm/defectdojo/templates/media-pvc.yaml b/helm/defectdojo/templates/media-pvc.yaml index 1eba1977e9f..c1ca40050d4 100644 --- a/helm/defectdojo/templates/media-pvc.yaml +++ b/helm/defectdojo/templates/media-pvc.yaml @@ -10,6 +10,9 @@ metadata: app.kubernetes.io/instance: {{ $.Release.Name }} app.kubernetes.io/managed-by: {{ $.Release.Service }} helm.sh/chart: {{ include "defectdojo.chart" $ }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} name: {{ $fullName }} spec: accessModes: diff --git a/helm/defectdojo/templates/network-policy.yaml b/helm/defectdojo/templates/network-policy.yaml index 80c55ddcfa3..ea0017fb1e6 100644 --- a/helm/defectdojo/templates/network-policy.yaml +++ b/helm/defectdojo/templates/network-policy.yaml @@ -9,26 +9,29 @@ metadata: app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ include "defectdojo.chart" . }} app.kubernetes.io/name: {{ include "defectdojo.name" . }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} spec: podSelector: matchLabels: app.kubernetes.io/instance: {{ .Release.Name }} - {{- if .Values.networkPolicy.ingress}} + {{- if .Values.networkPolicy.ingress }} ingress: - {{- toYaml .Values.networkPolicy.ingress | nindent 4 }} + {{- toYaml .Values.networkPolicy.ingress | nindent 4 }} {{- else }} ingress: - from: - podSelector: matchLabels: app.kubernetes.io/instance: {{ .Release.Name }} - {{- if .Values.networkPolicy.ingressExtend }} - {{- toYaml .Values.networkPolicy.ingressExtend | nindent 8 }} + {{- with .Values.networkPolicy.ingressExtend }} + {{- toYaml . | nindent 8 }} {{ end }} {{- end }} - {{- if .Values.networkPolicy.egress }} + {{- with .Values.networkPolicy.egress }} egress: - {{- toYaml .Values.networkPolicy.egress | nindent 4 }} + {{- toYaml . | nindent 4 }} {{ end }} --- apiVersion: networking.k8s.io/v1 @@ -40,6 +43,9 @@ metadata: app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ include "defectdojo.chart" . }} app.kubernetes.io/name: {{ include "defectdojo.name" . }} +{{- with .Values.extraLabels }} + {{- toYaml . | nindent 4 }} +{{- end }} spec: podSelector: matchLabels: diff --git a/helm/defectdojo/templates/sa.yaml b/helm/defectdojo/templates/sa.yaml index 46f1eaa6d97..23cb70ecd6e 100644 --- a/helm/defectdojo/templates/sa.yaml +++ b/helm/defectdojo/templates/sa.yaml @@ -8,6 +8,9 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ include "defectdojo.chart" . }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} annotations: helm.sh/resource-policy: keep helm.sh/hook: "pre-install" diff --git a/helm/defectdojo/templates/secret-postgresql-ha-pgpool.yaml b/helm/defectdojo/templates/secret-postgresql-ha-pgpool.yaml index 9a440efffd1..40906c1f180 100644 --- a/helm/defectdojo/templates/secret-postgresql-ha-pgpool.yaml +++ b/helm/defectdojo/templates/secret-postgresql-ha-pgpool.yaml @@ -8,6 +8,9 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ include "defectdojo.chart" . }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} annotations: helm.sh/resource-policy: keep helm.sh/hook: "pre-install" diff --git a/helm/defectdojo/templates/secret-postgresql-ha.yaml b/helm/defectdojo/templates/secret-postgresql-ha.yaml index 8e884fa0484..e9236a63f00 100644 --- a/helm/defectdojo/templates/secret-postgresql-ha.yaml +++ b/helm/defectdojo/templates/secret-postgresql-ha.yaml @@ -8,6 +8,9 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ include "defectdojo.chart" . }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} annotations: helm.sh/resource-policy: keep helm.sh/hook: "pre-install" diff --git a/helm/defectdojo/templates/secret-postgresql.yaml b/helm/defectdojo/templates/secret-postgresql.yaml index de6e65420b6..115c244baa5 100644 --- a/helm/defectdojo/templates/secret-postgresql.yaml +++ b/helm/defectdojo/templates/secret-postgresql.yaml @@ -8,6 +8,9 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ include "defectdojo.chart" . }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} annotations: helm.sh/resource-policy: keep helm.sh/hook: "pre-install" diff --git a/helm/defectdojo/templates/secret-redis.yaml b/helm/defectdojo/templates/secret-redis.yaml index 629e6b4fa93..de4549c1f63 100644 --- a/helm/defectdojo/templates/secret-redis.yaml +++ b/helm/defectdojo/templates/secret-redis.yaml @@ -8,6 +8,9 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ include "defectdojo.chart" . }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} annotations: helm.sh/resource-policy: keep helm.sh/hook: "pre-install" diff --git a/helm/defectdojo/templates/secret.yaml b/helm/defectdojo/templates/secret.yaml index 94ca3ef268b..500a097dd16 100644 --- a/helm/defectdojo/templates/secret.yaml +++ b/helm/defectdojo/templates/secret.yaml @@ -9,6 +9,9 @@ metadata: app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ include "defectdojo.chart" . }} + {{- with .Values.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} annotations: helm.sh/resource-policy: keep helm.sh/hook: "pre-install" diff --git a/helm/defectdojo/values.yaml b/helm/defectdojo/values.yaml index b2d0422bc2c..8cd5d0aca3b 100644 --- a/helm/defectdojo/values.yaml +++ b/helm/defectdojo/values.yaml @@ -16,6 +16,9 @@ createPostgresqlHaPgpoolSecret: false # - enabled, enables tracking configuration changes based on SHA256 # trackConfig: disabled +# extraLabels: {} +# Add extra labels for k8s + # Enables application network policy # For more info follow https://kubernetes.io/docs/concepts/services-networking/network-policies/ networkPolicy: @@ -234,13 +237,29 @@ django: tolerations: [] uwsgi: livenessProbe: - # Enable liveness checks on uwsgi container. Those values are use on nginx readiness checks as well. + # Enable liveness checks on uwsgi container. enabled: true failureThreshold: 6 - initialDelaySeconds: 3 + initialDelaySeconds: 0 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 5 + readinessProbe: + # Enable readiness checks on uwsgi container. + enabled: true + failureThreshold: 6 + initialDelaySeconds: 0 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + startupProbe: + # Enable startup checks on uwsgi container. + enabled: true + failureThreshold: 30 + initialDelaySeconds: 0 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 1 resources: requests: cpu: 100m @@ -321,7 +340,7 @@ initializer: jobAnnotations: {} annotations: {} labels: {} - keepSeconds: 60 + keepSeconds: 60 # A positive integer will keep this Job and Pod deployed for the specified number of seconds, after which they will be removed. For all other values, the Job and Pod will remain deployed. affinity: {} nodeSelector: {} resources: @@ -365,6 +384,11 @@ initializer: # @type: array