diff --git a/cmd/scripts.go b/cmd/scripts.go index 8959511fa..9a5123061 100644 --- a/cmd/scripts.go +++ b/cmd/scripts.go @@ -123,7 +123,7 @@ func createScript(provider *kubernetes.Provider, script misc.ConfigMapScript) (i } if k8serrors.IsConflict(err) { - log.Warn().Err(err).Msg("Conflict detected, retrying update...") + log.Debug().Err(err).Msg("Conflict detected, retrying update...") time.Sleep(500 * time.Millisecond) continue } @@ -332,23 +332,29 @@ func watchConfigMap(ctx context.Context, provider *kubernetes.Provider) { continue } - for event := range watcher.ResultChan() { - select { - case <-ctx.Done(): - log.Info().Msg("ConfigMap watcher loop exiting gracefully.") - watcher.Stop() - return - - default: + // Create a goroutine to process events + watcherClosed := make(chan struct{}) + go func() { + defer close(watcherClosed) + for event := range watcher.ResultChan() { if event.Type == watch.Added { log.Info().Msg("ConfigMap created or modified") runScriptsSync(provider) } else if event.Type == watch.Deleted { log.Warn().Msg("ConfigMap deleted, waiting for recreation...") - watcher.Stop() break } } + }() + + // Wait for either context cancellation or watcher completion + select { + case <-ctx.Done(): + watcher.Stop() + log.Info().Msg("ConfigMap watcher stopping due to context cancellation") + return + case <-watcherClosed: + log.Info().Msg("Watcher closed, restarting...") } time.Sleep(5 * time.Second) diff --git a/config/configStruct.go b/config/configStruct.go index a911dc64c..f794d001b 100644 --- a/config/configStruct.go +++ b/config/configStruct.go @@ -50,6 +50,17 @@ func CreateDefaultConfig() ConfigStruct { }, }, }, + Dex: []v1.NodeSelectorTerm{ + { + MatchExpressions: []v1.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: v1.NodeSelectorOpIn, + Values: []string{"linux"}, + }, + }, + }, + }, }, Tolerations: configStructs.TolerationsConfig{ Workers: []v1.Toleration{ @@ -135,6 +146,9 @@ func CreateDefaultConfig() ConfigStruct { LDAP: []uint16{389}, DIAMETER: []uint16{3868}, }, + Dashboard: configStructs.DashboardConfig{ + CompleteStreamingEnabled: true, + }, }, } } @@ -158,9 +172,9 @@ type ConfigStruct struct { HeadlessMode bool `yaml:"headless" json:"headless" default:"false"` License string `yaml:"license" json:"license" default:""` CloudLicenseEnabled bool `yaml:"cloudLicenseEnabled" json:"cloudLicenseEnabled" default:"true"` - AiAssistantEnabled bool `yaml:"aiAssistantEnabled" json:"aiAssistantEnabled" default:"false"` + AiAssistantEnabled bool `yaml:"aiAssistantEnabled" json:"aiAssistantEnabled" default:"true"` DemoModeEnabled bool `yaml:"demoModeEnabled" json:"demoModeEnabled" default:"false"` - SupportChatEnabled bool `yaml:"supportChatEnabled" json:"supportChatEnabled" default:"true"` + SupportChatEnabled bool `yaml:"supportChatEnabled" json:"supportChatEnabled" default:"false"` InternetConnectivity bool `yaml:"internetConnectivity" json:"internetConnectivity" default:"true"` Scripting configStructs.ScriptingConfig `yaml:"scripting" json:"scripting"` Manifests ManifestsConfig `yaml:"manifests,omitempty" json:"manifests,omitempty"` diff --git a/config/configStructs/tapConfig.go b/config/configStructs/tapConfig.go index 1be086b04..b2f2f650d 100644 --- a/config/configStructs/tapConfig.go +++ b/config/configStructs/tapConfig.go @@ -138,6 +138,7 @@ type NodeSelectorTermsConfig struct { Hub []v1.NodeSelectorTerm `yaml:"hub" json:"hub" default:"[]"` Workers []v1.NodeSelectorTerm `yaml:"workers" json:"workers" default:"[]"` Front []v1.NodeSelectorTerm `yaml:"front" json:"front" default:"[]"` + Dex []v1.NodeSelectorTerm `yaml:"dex" json:"dex" default:"[]"` } type TolerationsConfig struct { @@ -195,6 +196,10 @@ type RoutingConfig struct { Front FrontRoutingConfig `yaml:"front" json:"front"` } +type DashboardConfig struct { + CompleteStreamingEnabled bool `yaml:"completeStreamingEnabled" json:"completeStreamingEnabled" default:"true"` +} + type FrontRoutingConfig struct { BasePath string `yaml:"basePath" json:"basePath" default:""` } @@ -290,51 +295,53 @@ type SeLinuxOptionsConfig struct { } type TapConfig struct { - Docker DockerConfig `yaml:"docker" json:"docker"` - Proxy ProxyConfig `yaml:"proxy" json:"proxy"` - PodRegexStr string `yaml:"regex" json:"regex" default:".*"` - Namespaces []string `yaml:"namespaces" json:"namespaces" default:"[]"` - ExcludedNamespaces []string `yaml:"excludedNamespaces" json:"excludedNamespaces" default:"[]"` - BpfOverride string `yaml:"bpfOverride" json:"bpfOverride" default:""` - Stopped bool `yaml:"stopped" json:"stopped" default:"false"` - Release ReleaseConfig `yaml:"release" json:"release"` - PersistentStorage bool `yaml:"persistentStorage" json:"persistentStorage" default:"false"` - PersistentStorageStatic bool `yaml:"persistentStorageStatic" json:"persistentStorageStatic" default:"false"` - EfsFileSytemIdAndPath string `yaml:"efsFileSytemIdAndPath" json:"efsFileSytemIdAndPath" default:""` - StorageLimit string `yaml:"storageLimit" json:"storageLimit" default:"5000Mi"` - StorageClass string `yaml:"storageClass" json:"storageClass" default:"standard"` - DryRun bool `yaml:"dryRun" json:"dryRun" default:"false"` - DnsConfig DnsConfig `yaml:"dns" json:"dns"` - Resources ResourcesConfig `yaml:"resources" json:"resources"` - Probes ProbesConfig `yaml:"probes" json:"probes"` - ServiceMesh bool `yaml:"serviceMesh" json:"serviceMesh" default:"true"` - Tls bool `yaml:"tls" json:"tls" default:"true"` - DisableTlsLog bool `yaml:"disableTlsLog" json:"disableTlsLog" default:"true"` - PacketCapture string `yaml:"packetCapture" json:"packetCapture" default:"best"` - Labels map[string]string `yaml:"labels" json:"labels" default:"{}"` - Annotations map[string]string `yaml:"annotations" json:"annotations" default:"{}"` - NodeSelectorTerms NodeSelectorTermsConfig `yaml:"nodeSelectorTerms" json:"nodeSelectorTerms" default:"{}"` - Tolerations TolerationsConfig `yaml:"tolerations" json:"tolerations" default:"{}"` - Auth AuthConfig `yaml:"auth" json:"auth"` - Ingress IngressConfig `yaml:"ingress" json:"ingress"` - Routing RoutingConfig `yaml:"routing" json:"routing"` - IPv6 bool `yaml:"ipv6" json:"ipv6" default:"true"` - Debug bool `yaml:"debug" json:"debug" default:"false"` - Telemetry TelemetryConfig `yaml:"telemetry" json:"telemetry"` - ResourceGuard ResourceGuardConfig `yaml:"resourceGuard" json:"resourceGuard"` - Watchdog WatchdogConfig `yaml:"watchdog" json:"watchdog"` - Sentry SentryConfig `yaml:"sentry" json:"sentry"` - DefaultFilter string `yaml:"defaultFilter" json:"defaultFilter" default:"!dns and !error"` - LiveConfigMapChangesDisabled bool `yaml:"liveConfigMapChangesDisabled" json:"liveConfigMapChangesDisabled" default:"false"` - GlobalFilter string `yaml:"globalFilter" json:"globalFilter" default:""` - EnabledDissectors []string `yaml:"enabledDissectors" json:"enabledDissectors"` - PortMapping PortMapping `yaml:"portMapping" json:"portMapping"` - CustomMacros map[string]string `yaml:"customMacros" json:"customMacros" default:"{\"https\":\"tls and (http or http2)\"}"` - Metrics MetricsConfig `yaml:"metrics" json:"metrics"` - Pprof PprofConfig `yaml:"pprof" json:"pprof"` - Misc MiscConfig `yaml:"misc" json:"misc"` - SecurityContext SecurityContextConfig `yaml:"securityContext" json:"securityContext"` - MountBpf bool `yaml:"mountBpf" json:"mountBpf" default:"true"` + Docker DockerConfig `yaml:"docker" json:"docker"` + Proxy ProxyConfig `yaml:"proxy" json:"proxy"` + PodRegexStr string `yaml:"regex" json:"regex" default:".*"` + Namespaces []string `yaml:"namespaces" json:"namespaces" default:"[]"` + ExcludedNamespaces []string `yaml:"excludedNamespaces" json:"excludedNamespaces" default:"[]"` + BpfOverride string `yaml:"bpfOverride" json:"bpfOverride" default:""` + Stopped bool `yaml:"stopped" json:"stopped" default:"false"` + Release ReleaseConfig `yaml:"release" json:"release"` + PersistentStorage bool `yaml:"persistentStorage" json:"persistentStorage" default:"false"` + PersistentStorageStatic bool `yaml:"persistentStorageStatic" json:"persistentStorageStatic" default:"false"` + PersistentStoragePvcVolumeMode string `yaml:"persistentStoragePvcVolumeMode" json:"persistentStoragePvcVolumeMode" default:"FileSystem"` + EfsFileSytemIdAndPath string `yaml:"efsFileSytemIdAndPath" json:"efsFileSytemIdAndPath" default:""` + StorageLimit string `yaml:"storageLimit" json:"storageLimit" default:"5000Mi"` + StorageClass string `yaml:"storageClass" json:"storageClass" default:"standard"` + DryRun bool `yaml:"dryRun" json:"dryRun" default:"false"` + DnsConfig DnsConfig `yaml:"dns" json:"dns"` + Resources ResourcesConfig `yaml:"resources" json:"resources"` + Probes ProbesConfig `yaml:"probes" json:"probes"` + ServiceMesh bool `yaml:"serviceMesh" json:"serviceMesh" default:"true"` + Tls bool `yaml:"tls" json:"tls" default:"true"` + DisableTlsLog bool `yaml:"disableTlsLog" json:"disableTlsLog" default:"true"` + PacketCapture string `yaml:"packetCapture" json:"packetCapture" default:"best"` + Labels map[string]string `yaml:"labels" json:"labels" default:"{}"` + Annotations map[string]string `yaml:"annotations" json:"annotations" default:"{}"` + NodeSelectorTerms NodeSelectorTermsConfig `yaml:"nodeSelectorTerms" json:"nodeSelectorTerms" default:"{}"` + Tolerations TolerationsConfig `yaml:"tolerations" json:"tolerations" default:"{}"` + Auth AuthConfig `yaml:"auth" json:"auth"` + Ingress IngressConfig `yaml:"ingress" json:"ingress"` + Routing RoutingConfig `yaml:"routing" json:"routing"` + IPv6 bool `yaml:"ipv6" json:"ipv6" default:"true"` + Debug bool `yaml:"debug" json:"debug" default:"false"` + Dashboard DashboardConfig `yaml:"dashboard" json:"dashboard"` + Telemetry TelemetryConfig `yaml:"telemetry" json:"telemetry"` + ResourceGuard ResourceGuardConfig `yaml:"resourceGuard" json:"resourceGuard"` + Watchdog WatchdogConfig `yaml:"watchdog" json:"watchdog"` + Sentry SentryConfig `yaml:"sentry" json:"sentry"` + DefaultFilter string `yaml:"defaultFilter" json:"defaultFilter" default:"!dns and !error"` + LiveConfigMapChangesDisabled bool `yaml:"liveConfigMapChangesDisabled" json:"liveConfigMapChangesDisabled" default:"false"` + GlobalFilter string `yaml:"globalFilter" json:"globalFilter" default:""` + EnabledDissectors []string `yaml:"enabledDissectors" json:"enabledDissectors"` + PortMapping PortMapping `yaml:"portMapping" json:"portMapping"` + CustomMacros map[string]string `yaml:"customMacros" json:"customMacros" default:"{\"https\":\"tls and (http or http2)\"}"` + Metrics MetricsConfig `yaml:"metrics" json:"metrics"` + Pprof PprofConfig `yaml:"pprof" json:"pprof"` + Misc MiscConfig `yaml:"misc" json:"misc"` + SecurityContext SecurityContextConfig `yaml:"securityContext" json:"securityContext"` + MountBpf bool `yaml:"mountBpf" json:"mountBpf" default:"true"` } func (config *TapConfig) PodRegex() *regexp.Regexp { diff --git a/helm-chart/README.md b/helm-chart/README.md index c18b30137..bfae9388a 100644 --- a/helm-chart/README.md +++ b/helm-chart/README.md @@ -144,6 +144,7 @@ Example for overriding image names: | `tap.release.namespace` | Helm release namespace | `default` | | `tap.persistentStorage` | Use `persistentVolumeClaim` instead of `emptyDir` | `false` | | `tap.persistentStorageStatic` | Use static persistent volume provisioning (explicitly defined `PersistentVolume` ) | `false` | +| `tap.persistentStoragePvcVolumeMode` | Set the pvc volume mode (Filesystem\|Block) | `Filesystem` | | `tap.efsFileSytemIdAndPath` | [EFS file system ID and, optionally, subpath and/or access point](https://github.com/kubernetes-sigs/aws-efs-csi-driver/blob/master/examples/kubernetes/access_points/README.md) `::` | "" | | `tap.storageLimit` | Limit of either the `emptyDir` or `persistentVolumeClaim` | `500Mi` | | `tap.storageClass` | Storage class of the `PersistentVolumeClaim` | `standard` | @@ -222,7 +223,7 @@ Example for overriding image names: | `scripting.source` | Source directory of the scripts | `""` | | `scripting.watchScripts` | Enable watch mode for the scripts in source directory | `true` | | `timezone` | IANA time zone applied to time shown in the front-end | `""` (local time zone applies) | -| `supportChatEnabled` | Enable real-time support chat channel based on Intercom | `true` | +| `supportChatEnabled` | Enable real-time support chat channel based on Intercom | `false` | | `internetConnectivity` | Turns off API requests that are dependant on Internet connectivity such as `telemetry` and `online-support`. | `true` | KernelMapping pairs kernel versions with a @@ -351,8 +352,20 @@ tap: clientSecret: create your own client password refreshTokenLifetime: "3960h" # 165 days oauth2StateParamExpiry: "10m" + bypassSslCaCheck: false ``` +--- + +**Note:**
+Set `tap.auth.dexOidc.bypassSslCaCheck: true` +to allow Kubeshark communication with Dex IdP having an unknown SSL Certificate Authority. + +This setting allows you to prevent such SSL CA-related errors:
+`tls: failed to verify certificate: x509: certificate signed by unknown authority` + +--- + Once you run `helm install kubeshark kubeshark/kubeshark -f ./values.yaml`, Kubeshark will be installed with (Dex) OIDC authentication enabled. --- @@ -443,6 +456,7 @@ tap: refreshTokenLifetime: "3960h" # 165 days oauth2StateParamExpiry: "10m" + bypassSslCaCheck: false dexConfig: # This field is REQUIRED! # diff --git a/helm-chart/templates/02-cluster-role.yaml b/helm-chart/templates/02-cluster-role.yaml index 6b5094ac4..add390390 100644 --- a/helm-chart/templates/02-cluster-role.yaml +++ b/helm-chart/templates/02-cluster-role.yaml @@ -82,5 +82,7 @@ rules: resources: - secrets - configmaps + - pods/log verbs: - create + - get \ No newline at end of file diff --git a/helm-chart/templates/06-front-deployment.yaml b/helm-chart/templates/06-front-deployment.yaml index 1644bf450..6fd699df5 100644 --- a/helm-chart/templates/06-front-deployment.yaml +++ b/helm-chart/templates/06-front-deployment.yaml @@ -36,6 +36,12 @@ spec: {{- else -}} {{ .Values.tap.auth.type }} {{- end }}' + - name: REACT_APP_COMPLETE_STREAMING_ENABLED + value: '{{- if and (hasKey .Values.tap "dashboard") (hasKey .Values.tap.dashboard "completeStreamingEnabled") -}} + {{ eq .Values.tap.dashboard.completeStreamingEnabled true | ternary "true" "false" }} + {{- else -}} + true + {{- end }}' - name: REACT_APP_AUTH_SAML_IDP_METADATA_URL value: '{{ not (eq .Values.tap.auth.saml.idpMetadataUrl "") | ternary .Values.tap.auth.saml.idpMetadataUrl " " }}' - name: REACT_APP_TIMEZONE diff --git a/helm-chart/templates/08-persistent-volume-claim.yaml b/helm-chart/templates/08-persistent-volume-claim.yaml index 079899161..49c4cb4c5 100644 --- a/helm-chart/templates/08-persistent-volume-claim.yaml +++ b/helm-chart/templates/08-persistent-volume-claim.yaml @@ -33,6 +33,7 @@ metadata: name: kubeshark-persistent-volume-claim namespace: {{ .Release.Namespace }} spec: + volumeMode: {{ .Values.tap.persistentStoragePvcVolumeMode }} accessModes: - ReadWriteMany resources: diff --git a/helm-chart/templates/12-config-map.yaml b/helm-chart/templates/12-config-map.yaml index 6239aaa88..b356be53a 100644 --- a/helm-chart/templates/12-config-map.yaml +++ b/helm-chart/templates/12-config-map.yaml @@ -33,6 +33,15 @@ data: AUTH_OIDC_ISSUER: '{{ default "not set" (((.Values.tap).auth).dexOidc).issuer }}' AUTH_OIDC_REFRESH_TOKEN_LIFETIME: '{{ default "3960h" (((.Values.tap).auth).dexOidc).refreshTokenLifetime }}' AUTH_OIDC_STATE_PARAM_EXPIRY: '{{ default "10m" (((.Values.tap).auth).dexOidc).oauth2StateParamExpiry }}' + AUTH_OIDC_BYPASS_SSL_CA_CHECK: '{{- if and + (hasKey .Values.tap "auth") + (hasKey .Values.tap.auth "dexOidc") + (hasKey .Values.tap.auth.dexOidc "bypassSslCaCheck") + -}} + {{ eq .Values.tap.auth.dexOidc.bypassSslCaCheck true | ternary "true" "false" }} + {{- else -}} + false + {{- end }}' TELEMETRY_DISABLED: '{{ not .Values.internetConnectivity | ternary "true" (not .Values.tap.telemetry.enabled | ternary "true" "false") }}' SCRIPTING_DISABLED: '{{- if .Values.tap.liveConfigMapChangesDisabled -}} {{- if .Values.demoModeEnabled -}} diff --git a/helm-chart/templates/NOTES.txt b/helm-chart/templates/NOTES.txt index b1a6a1d72..1beaa0e5d 100644 --- a/helm-chart/templates/NOTES.txt +++ b/helm-chart/templates/NOTES.txt @@ -28,7 +28,7 @@ Notices: - Support chat using Intercom is enabled. It can be disabled using `--set supportChatEnabled=false` {{- end }} {{- if eq .Values.license ""}} -- No license key was detected. You can get your license key from https://console.kubeshark.co/. +- No license key was detected. You can either log-in/sign-up through the dashboard, or download the license key from https://console.kubeshark.co/. {{- end }} {{ if .Values.tap.ingress.enabled }} diff --git a/helm-chart/values.yaml b/helm-chart/values.yaml index 97342ca36..e3921539c 100644 --- a/helm-chart/values.yaml +++ b/helm-chart/values.yaml @@ -33,6 +33,7 @@ tap: namespace: default persistentStorage: false persistentStorageStatic: false + persistentStoragePvcVolumeMode: FileSystem efsFileSytemIdAndPath: "" storageLimit: 5000Mi storageClass: standard @@ -99,6 +100,7 @@ tap: operator: In values: - linux + dex: [] tolerations: hub: [] workers: @@ -136,6 +138,8 @@ tap: basePath: "" ipv6: true debug: false + dashboard: + completeStreamingEnabled: true telemetry: enabled: true resourceGuard: @@ -238,9 +242,9 @@ dumpLogs: false headless: false license: "" cloudLicenseEnabled: true -aiAssistantEnabled: false +aiAssistantEnabled: true demoModeEnabled: false -supportChatEnabled: true +supportChatEnabled: false internetConnectivity: true scripting: env: {}