chart: drop demoModeEnabled in favour of auth.defaultRole

The demo is now a configuration of the knobs every deployment has rather than
a mode of its own: tap.auth.enabled false so nobody logs in, and
tap.auth.defaultRole kubeshark-viewer so an unidentified caller may only read.
The Hub enforces that role on REST, MCP and Connect-RPC alike, so the keys
this flag used to render are redundant with it.

Scripting is the exception, because "may this caller run scripts" is not a
capability anyone holds. It stays a deployment-wide switch and now follows
scripting.enabled, the value that already decides whether scripting exists
for an install. Until now a default install hid the scripting UI while the
/scripts API kept answering.

DISSECTION_CONTROL_ENABLED goes rather than losing its demo term: with the
flag gone both branches of that expression render true.

The suites in tests/ carry the reasoning, since nothing named demo survives
in the templates for a reader to follow.
This commit is contained in:
Volodymyr Stoiko
2026-08-27 12:33:32 +03:00
parent 793e5d1efa
commit bbe87f5317
7 changed files with 86 additions and 56 deletions
-1
View File
@@ -177,7 +177,6 @@ type ConfigStruct struct {
License string `yaml:"license" json:"license" default:""`
CloudApiUrl string `yaml:"cloudApiUrl" json:"cloudApiUrl" default:"https://api.kubeshark.com"`
CloudLicenseEnabled bool `yaml:"cloudLicenseEnabled" json:"cloudLicenseEnabled" default:"true"`
DemoModeEnabled bool `yaml:"demoModeEnabled" json:"demoModeEnabled" default:"false"`
SupportChatEnabled bool `yaml:"supportChatEnabled" json:"supportChatEnabled" default:"false"`
BetaEnabled bool `yaml:"betaEnabled" json:"betaEnabled" default:"false"`
InternetConnectivity bool `yaml:"internetConnectivity" json:"internetConnectivity" default:"true"`
+1 -19
View File
@@ -47,23 +47,11 @@ spec:
false
{{- end }}'
- name: REACT_APP_SCRIPTING_DISABLED
value: '{{ default false .Values.demoModeEnabled }}'
- name: REACT_APP_TARGETED_PODS_UPDATE_DISABLED
value: '{{ default false .Values.demoModeEnabled }}'
- name: REACT_APP_PRESET_FILTERS_CHANGING_ENABLED
value: '{{ not (default false .Values.demoModeEnabled) }}'
value: '{{ not (default false ((.Values.scripting).enabled)) }}'
- name: REACT_APP_BPF_OVERRIDE_DISABLED
value: '{{ eq .Values.tap.packetCapture "af_packet" | ternary "false" "true" }}'
- name: REACT_APP_RECORDING_DISABLED
value: '{{ default false .Values.demoModeEnabled }}'
- name: REACT_APP_DISSECTION_ENABLED
value: '{{ .Values.tap.capture.dissection.enabled | ternary "true" "false" }}'
- name: REACT_APP_DISSECTION_CONTROL_ENABLED
value: '{{- if and (not .Values.demoModeEnabled) (not .Values.tap.capture.dissection.enabled) -}}
true
{{- else -}}
{{ (default false .Values.demoModeEnabled) | ternary false true }}
{{- end -}}'
- name: 'REACT_APP_CLOUD_LICENSE_ENABLED'
value: '{{- if or (and .Values.cloudLicenseEnabled (not (empty .Values.license))) (not .Values.internetConnectivity) -}}
false
@@ -74,12 +62,6 @@ spec:
value: '{{ and .Values.supportChatEnabled .Values.internetConnectivity | ternary "true" "false" }}'
- name: REACT_APP_BETA_ENABLED
value: '{{ default false .Values.betaEnabled | ternary "true" "false" }}'
- name: REACT_APP_DISSECTORS_UPDATING_ENABLED
value: '{{ not (default false .Values.demoModeEnabled) }}'
- name: REACT_APP_SNAPSHOTS_UPDATING_ENABLED
value: '{{ not (default false .Values.demoModeEnabled) }}'
- name: REACT_APP_DEMO_MODE_ENABLED
value: '{{ default false .Values.demoModeEnabled }}'
- name: REACT_APP_CLUSTER_WIDE_MAP_ENABLED
value: '{{ default false (((.Values).tap).dashboard).clusterWideMapEnabled }}'
- name: REACT_APP_RAW_CAPTURE_ENABLED
+1 -12
View File
@@ -40,15 +40,7 @@ data:
false
{{- end }}'
TELEMETRY_DISABLED: '{{ not .Values.internetConnectivity | ternary "true" (not .Values.tap.telemetry.enabled | ternary "true" "false") }}'
SCRIPTING_DISABLED: '{{ default false .Values.demoModeEnabled }}'
TARGETED_PODS_UPDATE_DISABLED: '{{ default false .Values.demoModeEnabled }}'
PRESET_FILTERS_CHANGING_ENABLED: '{{ not (default false .Values.demoModeEnabled) }}'
RECORDING_DISABLED: '{{ (default false .Values.demoModeEnabled) | ternary true false }}'
DISSECTION_CONTROL_ENABLED: '{{- if and (not .Values.demoModeEnabled) (not .Values.tap.capture.dissection.enabled) -}}
true
{{- else -}}
{{ (default false .Values.demoModeEnabled) | ternary false true }}
{{- end }}'
SCRIPTING_DISABLED: '{{ not (default false ((.Values.scripting).enabled)) }}'
GLOBAL_FILTER: {{ include "kubeshark.escapeDoubleQuotes" .Values.tap.globalFilter | quote }}
DEFAULT_FILTER: {{ include "kubeshark.escapeDoubleQuotes" .Values.tap.defaultFilter | quote }}
TRAFFIC_SAMPLE_RATE: '{{ .Values.tap.misc.trafficSampleRate }}'
@@ -64,9 +56,6 @@ data:
DUPLICATE_TIMEFRAME: '{{ .Values.tap.misc.duplicateTimeframe }}'
ENABLED_DISSECTORS: '{{ gt (len .Values.tap.enabledDissectors) 0 | ternary (join "," .Values.tap.enabledDissectors) "" }}'
CUSTOM_MACROS: '{{ toJson .Values.tap.customMacros }}'
DISSECTORS_UPDATING_ENABLED: '{{ not (default false .Values.demoModeEnabled) }}'
SNAPSHOTS_UPDATING_ENABLED: '{{ not (default false .Values.demoModeEnabled) }}'
DEMO_MODE_ENABLED: '{{ default false .Values.demoModeEnabled }}'
DETECT_DUPLICATES: '{{ .Values.tap.misc.detectDuplicates | ternary "true" "false" }}'
PCAP_DUMP_ENABLE: '{{ .Values.pcapdump.enabled }}'
PCAP_TIME_INTERVAL: '{{ .Values.pcapdump.timeInterval }}'
+3 -21
View File
@@ -6,7 +6,7 @@
## * Is the API gated? -> tap.auth.enabled
## * Does the dashboard need a login -> cloudLicenseEnabled + license +
## to fetch a licence key? internetConnectivity (front only)
## * Which features exist at all? -> demoModeEnabled
## * What may an unidentified caller do? -> tap.auth.defaultRole
##
## These tests pin each answer to its own input, so a future change that
## reconnects them fails here rather than in someone's cluster.
@@ -71,19 +71,11 @@ tests:
path: data.AUTH_TYPE
value: saml
- it: is not turned on by demo mode
set:
demoModeEnabled: true
asserts:
- equal:
path: data.AUTH_ENABLED
value: "false"
## AUTH_TYPE is the operator's choice, verbatim.
##
## It used to be rewritten to "default" whenever cloud licensing was on and
## the type was not oidc/dex, and unconditionally under demo mode. An
## operator's `saml` therefore became something else on a live cluster.
## the type was not oidc/dex. An operator's `saml` therefore became
## something else on a live cluster.
- it: passes the configured auth type through unchanged
set:
@@ -106,16 +98,6 @@ tests:
path: data.AUTH_TYPE
value: oidc
- it: does not rewrite the auth type under demo mode
set:
demoModeEnabled: true
tap.auth.enabled: true
tap.auth.type: descope
asserts:
- equal:
path: data.AUTH_TYPE
value: descope
## AUTH_DEFAULT_ROLE decides what a caller with no recognized group may do,
## including a caller on a deployment with no authentication at all. Its
## default is admin, so an ungated install behaves as it always has; a
+80
View File
@@ -0,0 +1,80 @@
suite: demo posture
templates:
- templates/12-config-map.yaml
## The demo used to be a product mode: `demoModeEnabled: true` fanned out into
## eight ConfigMap keys, and the Hub read each one to decide whether a route
## answered or returned 409. Every one of those restrictions that is really a
## question of "what may this caller do" is now answered by the role instead,
## so the demo is a configuration of the same knobs every other deployment has:
##
## tap.auth.enabled: false -> no identity, nobody logs in
## tap.auth.defaultRole: viewer -> and an unidentified caller may only read
##
## These tests exist because that equivalence is invisible in the templates:
## nothing named "demo" remains to read, so only a test can state that the
## keys are gone and that no value brings them back.
tests:
- it: renders none of the keys the demo flag used to fan out into
asserts:
- notExists:
path: data.DEMO_MODE_ENABLED
- notExists:
path: data.TARGETED_PODS_UPDATE_DISABLED
- notExists:
path: data.PRESET_FILTERS_CHANGING_ENABLED
- notExists:
path: data.RECORDING_DISABLED
- notExists:
path: data.DISSECTION_CONTROL_ENABLED
- notExists:
path: data.DISSECTORS_UPDATING_ENABLED
- notExists:
path: data.SNAPSHOTS_UPDATING_ENABLED
## demoModeEnabled is not a value any more. Helm accepts unknown --set keys
## silently, so an operator carrying the old line in their values file gets
## no error; what they must not get is the old behaviour reappearing.
- it: ignores a leftover demoModeEnabled in an operator's values
set:
demoModeEnabled: true
asserts:
- notExists:
path: data.DEMO_MODE_ENABLED
- equal:
path: data.AUTH_ENABLED
value: "false"
## The demo posture itself. Nothing here is demo-specific; it is the same
## pair of values any read-only deployment would set.
- it: renders the demo as an ungated deployment pinned to viewer
set:
tap.auth.enabled: false
tap.auth.defaultRole: kubeshark-viewer
asserts:
- equal:
path: data.AUTH_ENABLED
value: "false"
- equal:
path: data.AUTH_DEFAULT_ROLE
value: kubeshark-viewer
## Scripting is the one restriction that is not a capability. It stays a
## deployment-wide switch, but it now follows the value that already decides
## whether scripting exists for this install rather than riding on the demo
## flag. Before this, a default install hid the scripting UI while leaving
## the /scripts API answering.
- it: disables the scripting API when scripting is not enabled
asserts:
- equal:
path: data.SCRIPTING_DISABLED
value: "true"
- it: enables the scripting API when scripting is enabled
set:
scripting.enabled: true
asserts:
- equal:
path: data.SCRIPTING_DISABLED
value: "false"
+1 -2
View File
@@ -73,10 +73,9 @@ tests:
# The projection is independent of everything that used to feed the old
# auth expression, not just of tap.auth.enabled.
- it: projects the token regardless of licensing or demo mode
- it: projects the token regardless of licensing
set:
license: ABC
demoModeEnabled: true
cloudLicenseEnabled: false
asserts:
- contains:
-1
View File
@@ -301,7 +301,6 @@ headless: false
license: ""
cloudApiUrl: https://api.kubeshark.com
cloudLicenseEnabled: true
demoModeEnabled: false
supportChatEnabled: false
betaEnabled: false
internetConnectivity: true