源码快照 @ 2026-09-02 (source-only, 剔除非源码素材)

This commit is contained in:
agent-radar
2026-09-02 01:05:41 +08:00
commit 04bac1f6e2
2200 changed files with 489415 additions and 0 deletions
@@ -0,0 +1,26 @@
OpenWork EE has been rendered with:
DEN_BASE_URL={{ .Values.config.public.webOrigin }}
DEN_BASE_URL is now the primary public Den URL. den-api derives Better Auth,
CORS/trusted origins, web-app hosts, API defaults, and MCP resource defaults
from this value unless compatibility overrides are set.
{{- $overrides := list -}}
{{- if .Values.config.public.apiOrigin }}{{- $overrides = append $overrides (printf "config.public.apiOrigin=%s" .Values.config.public.apiOrigin) -}}{{- end -}}
{{- if .Values.config.public.mcpResourceUrl }}{{- $overrides = append $overrides (printf "config.public.mcpResourceUrl=%s" .Values.config.public.mcpResourceUrl) -}}{{- end -}}
{{- if .Values.config.public.desktopDenBaseUrl }}{{- $overrides = append $overrides (printf "config.public.desktopDenBaseUrl=%s" .Values.config.public.desktopDenBaseUrl) -}}{{- end -}}
{{- if .Values.config.public.corsOrigins }}{{- $overrides = append $overrides (printf "config.public.corsOrigins=%s" .Values.config.public.corsOrigins) -}}{{- end -}}
{{- if .Values.config.public.betterAuthTrustedOrigins }}{{- $overrides = append $overrides (printf "config.public.betterAuthTrustedOrigins=%s" .Values.config.public.betterAuthTrustedOrigins) -}}{{- end -}}
{{- if .Values.config.public.webAppHosts }}{{- $overrides = append $overrides (printf "config.public.webAppHosts=%s" .Values.config.public.webAppHosts) -}}{{- end -}}
{{- if gt (len $overrides) 0 }}
Compatibility URL overrides are still set:
{{- range $overrides }}
- {{ . }}
{{- end }}
Keep these only for a deliberate split-origin/migration topology. For the
single-origin recommended deployment, clear them so Den derives the values from
config.public.webOrigin.
{{- end }}
@@ -0,0 +1,259 @@
{{- define "openwork-ee.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- define "openwork-ee.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- define "openwork-ee.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- define "openwork-ee.selectorLabels" -}}
app.kubernetes.io/name: {{ include "openwork-ee.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{- define "openwork-ee.labels" -}}
helm.sh/chart: {{ include "openwork-ee.chart" . }}
{{ include "openwork-ee.selectorLabels" . }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{- define "openwork-ee.componentSelectorLabels" -}}
{{ include "openwork-ee.selectorLabels" .root }}
app.kubernetes.io/component: {{ .component }}
{{- end -}}
{{- define "openwork-ee.componentLabels" -}}
{{ include "openwork-ee.labels" .root }}
app.kubernetes.io/component: {{ .component }}
{{- end -}}
{{- define "openwork-ee.configName" -}}
{{ include "openwork-ee.fullname" . }}-config
{{- end -}}
{{- define "openwork-ee.allowPrivateMcpUrls" -}}
{{- $value := .Values.config.public.allowPrivateMcpUrls | default "" | toString | trim | lower -}}
{{- if eq $value "1" -}}
1
{{- else if or (eq $value "") (eq $value "0") (eq $value "false") -}}
{{- else -}}
{{- fail "config.public.allowPrivateMcpUrls must be blank, 0, false, or \"1\"" -}}
{{- end -}}
{{- end -}}
{{- define "openwork-ee.secretName" -}}
{{- if .Values.secret.existingSecret -}}
{{- .Values.secret.existingSecret -}}
{{- else -}}
{{- include "openwork-ee.fullname" . }}-secret
{{- end -}}
{{- end -}}
{{- define "openwork-ee.denApiServiceName" -}}
{{ include "openwork-ee.fullname" . }}-den-api
{{- end -}}
{{- define "openwork-ee.denWebServiceName" -}}
{{ include "openwork-ee.fullname" . }}-den-web
{{- end -}}
{{- define "openwork-ee.inferenceServiceName" -}}
{{ include "openwork-ee.fullname" . }}-inference
{{- end -}}
{{- define "openwork-ee.denApiInternalUrl" -}}
{{- default (printf "http://%s:%v" (include "openwork-ee.denApiServiceName" .) .Values.denApi.service.port) .Values.config.internal.apiBaseUrl -}}
{{- end -}}
{{- define "openwork-ee.authFallbackInternalUrl" -}}
{{- default (include "openwork-ee.denApiInternalUrl" .) .Values.config.internal.authFallbackBaseUrl -}}
{{- end -}}
{{- define "openwork-ee.inferenceInternalUrl" -}}
{{- default (printf "http://%s:%v" (include "openwork-ee.inferenceServiceName" .) .Values.inference.service.port) .Values.config.internal.inferenceProxyBaseUrl -}}
{{- end -}}
{{- define "openwork-ee.customCa.mountPath" -}}
/etc/openwork/custom-ca
{{- end -}}
{{- define "openwork-ee.customCa.filePath" -}}
{{ include "openwork-ee.customCa.mountPath" . }}/ca-bundle.pem
{{- end -}}
{{- define "openwork-ee.customCa.validate" -}}
{{- if .Values.customCa.enabled -}}
{{- if and .Values.customCa.existingSecret .Values.customCa.existingConfigMap -}}
{{- fail "customCa.existingSecret and customCa.existingConfigMap are mutually exclusive when customCa.enabled=true" -}}
{{- end -}}
{{- if not (or .Values.customCa.existingSecret .Values.customCa.existingConfigMap) -}}
{{- fail "customCa.existingSecret or customCa.existingConfigMap is required when customCa.enabled=true" -}}
{{- end -}}
{{- if not .Values.customCa.key -}}
{{- fail "customCa.key is required when customCa.enabled=true" -}}
{{- end -}}
{{- if hasKey .Values.denApi.env "NODE_EXTRA_CA_CERTS" -}}
{{- fail "denApi.env.NODE_EXTRA_CA_CERTS conflicts with customCa.enabled=true; remove it and use customCa instead" -}}
{{- end -}}
{{- if hasKey .Values.denWeb.env "NODE_EXTRA_CA_CERTS" -}}
{{- fail "denWeb.env.NODE_EXTRA_CA_CERTS conflicts with customCa.enabled=true; remove it and use customCa instead" -}}
{{- end -}}
{{- if hasKey .Values.inference.env "NODE_EXTRA_CA_CERTS" -}}
{{- fail "inference.env.NODE_EXTRA_CA_CERTS conflicts with customCa.enabled=true; remove it and use customCa instead" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- define "openwork-ee.customCa.volume" -}}
- name: custom-ca
{{- if .Values.customCa.existingSecret }}
secret:
secretName: {{ .Values.customCa.existingSecret | quote }}
items:
- key: {{ .Values.customCa.key | quote }}
path: ca-bundle.pem
{{- else }}
configMap:
name: {{ .Values.customCa.existingConfigMap | quote }}
items:
- key: {{ .Values.customCa.key | quote }}
path: ca-bundle.pem
{{- end }}
{{- end -}}
{{- define "openwork-ee.customCa.volumeMount" -}}
- name: custom-ca
mountPath: {{ include "openwork-ee.customCa.mountPath" . | quote }}
readOnly: true
{{- end -}}
{{- define "openwork-ee.customCa.env" -}}
- name: NODE_EXTRA_CA_CERTS
value: {{ include "openwork-ee.customCa.filePath" . | quote }}
{{- end -}}
{{- define "openwork-ee.observabilityBackend" -}}
{{- $backend := default "none" .Values.observability.backend -}}
{{- if not (has $backend (list "none" "otel" "sentry")) -}}
{{- fail "observability.backend must be one of none, otel, sentry" -}}
{{- end -}}
{{- $backend -}}
{{- end -}}
{{- define "openwork-ee.observabilityOtelExporter" -}}
{{- $exporter := default "otlp" .value -}}
{{- if not (has $exporter (list "otlp" "none")) -}}
{{- fail (printf "observability.otel.exporters.%s must be otlp or none" .signal) -}}
{{- end -}}
{{- $exporter -}}
{{- end -}}
{{- define "openwork-ee.observabilityOtelSampler" -}}
{{- $sampler := default "parentbased_always_on" . -}}
{{- if not (has $sampler (list "always_on" "always_off" "traceidratio" "parentbased_always_on" "parentbased_always_off" "parentbased_traceidratio")) -}}
{{- fail "observability.otel.tracesSampler must be a standard OpenTelemetry sampler" -}}
{{- end -}}
{{- $sampler -}}
{{- end -}}
{{- define "openwork-ee.observabilityEnv" -}}
{{- $root := .root -}}
{{- $serviceName := .serviceName -}}
{{- $backend := include "openwork-ee.observabilityBackend" $root -}}
{{- $otel := $root.Values.observability.otel -}}
{{- $sentry := $root.Values.observability.sentry -}}
- name: DEN_OBSERVABILITY_BACKEND
value: {{ $backend | quote }}
- name: OTEL_SERVICE_NAME
value: {{ $serviceName | quote }}
{{- if eq $backend "otel" }}
{{- $otelSampler := include "openwork-ee.observabilityOtelSampler" $otel.tracesSampler -}}
{{- $otelProtocol := default "http/protobuf" $otel.protocol -}}
{{- if ne $otelProtocol "http/protobuf" }}
{{- fail "observability.otel.protocol must be http/protobuf" -}}
{{- end }}
- name: OTEL_EXPORTER_OTLP_PROTOCOL
value: {{ $otelProtocol | quote }}
{{- with $otel.endpoint }}
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: {{ . | quote }}
{{- end }}
{{- with $otel.tracesEndpoint }}
- name: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
value: {{ . | quote }}
{{- end }}
{{- with $otel.metricsEndpoint }}
- name: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
value: {{ . | quote }}
{{- end }}
{{- with $otel.logsEndpoint }}
- name: OTEL_EXPORTER_OTLP_LOGS_ENDPOINT
value: {{ . | quote }}
{{- end }}
- name: OTEL_TRACES_EXPORTER
value: {{ include "openwork-ee.observabilityOtelExporter" (dict "signal" "traces" "value" $otel.exporters.traces) | quote }}
- name: OTEL_METRICS_EXPORTER
value: {{ include "openwork-ee.observabilityOtelExporter" (dict "signal" "metrics" "value" $otel.exporters.metrics) | quote }}
- name: OTEL_LOGS_EXPORTER
value: {{ include "openwork-ee.observabilityOtelExporter" (dict "signal" "logs" "value" $otel.exporters.logs) | quote }}
- name: OTEL_TRACES_SAMPLER
value: {{ $otelSampler | quote }}
{{- if has $otelSampler (list "traceidratio" "parentbased_traceidratio") }}
- name: OTEL_TRACES_SAMPLER_ARG
value: {{ default "1" $otel.tracesSamplerArg | quote }}
{{- else if and $otel.tracesSamplerArg (ne (toString $otel.tracesSamplerArg) "1") }}
{{- fail "observability.otel.tracesSamplerArg is only supported for traceidratio samplers" -}}
{{- end }}
{{- with $otel.headers.existingSecret }}
- name: OTEL_EXPORTER_OTLP_HEADERS
valueFrom:
secretKeyRef:
name: {{ . | quote }}
key: {{ $otel.headers.key | quote }}
{{- end }}
{{- else if eq $backend "sentry" }}
{{- if and $sentry.dsn $sentry.dsnSecret.existingSecret }}
{{- fail "observability.sentry.dsn and observability.sentry.dsnSecret.existingSecret are mutually exclusive" -}}
{{- end }}
{{- if not (or $sentry.dsn $sentry.dsnSecret.existingSecret) }}
{{- fail "observability.sentry.dsn or observability.sentry.dsnSecret.existingSecret is required when observability.backend=sentry" -}}
{{- end }}
- name: SENTRY_DSN
{{- if $sentry.dsn }}
value: {{ $sentry.dsn | quote }}
{{- else }}
valueFrom:
secretKeyRef:
name: {{ $sentry.dsnSecret.existingSecret | quote }}
key: {{ $sentry.dsnSecret.key | quote }}
{{- end }}
- name: SENTRY_TRACES_SAMPLE_RATE
value: {{ $sentry.tracesSampleRate | quote }}
{{- with $sentry.environment }}
- name: SENTRY_ENVIRONMENT
value: {{ . | quote }}
{{- end }}
{{- with $sentry.release }}
- name: SENTRY_RELEASE
value: {{ . | quote }}
{{- end }}
{{- with $sentry.dist }}
- name: SENTRY_DIST
value: {{ . | quote }}
{{- end }}
{{- end }}
{{- end -}}
@@ -0,0 +1,200 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "openwork-ee.configName" . }}
labels:
{{- include "openwork-ee.labels" . | nindent 4 }}
data:
CI: "true"
NODE_ENV: "production"
OPENWORK_DEV_MODE: {{ .Values.config.openworkDevMode | quote }}
DEN_API_NODE_OPTIONS: {{ .Values.config.denApiNodeOptions | quote }}
# SECURITY: Enables non-local redis:// DATABASE_REDIS_URL values only for
# trusted private networks. Keep false for public or cross-network Redis;
# prefer rediss:// whenever the provider supports TLS.
DATABASE_REDIS_ALLOW_INSECURE_INTERNAL: {{ ternary "1" "0" .Values.redis.allowInsecureInternal | quote }}
DB_MODE: {{ .Values.config.databaseMode | quote }}
DEN_ORG_MODE: {{ .Values.config.tenancy.mode | quote }}
DEN_SINGLE_ORG_NAME: {{ .Values.config.tenancy.singleOrgName | quote }}
DEN_SINGLE_ORG_SLUG: {{ .Values.config.tenancy.singleOrgSlug | quote }}
DEN_SINGLE_ORG_OWNER_EMAILS: {{ .Values.config.tenancy.ownerEmails | quote }}
DEN_SINGLE_ORG_ALLOW_PUBLIC_SIGNUP: {{ .Values.config.tenancy.allowPublicSignup | quote }}
DEN_REQUIRE_EMAIL_VERIFICATION: {{ .Values.config.tenancy.requireEmailVerification | quote }}
DEN_PASSWORD_BREACH_SCREENING_ENABLED: {{ .Values.config.auth.passwordBreachScreeningEnabled | quote }}
GITHUB_CONNECTOR_APP_ID: {{ .Values.config.githubConnector.appId | quote }}
GITHUB_CONNECTOR_APP_CLIENT_ID: {{ .Values.config.githubConnector.clientId | quote }}
DEN_BASE_URL: {{ .Values.config.public.webOrigin | quote }}
{{ if .Values.config.public.webOrigin }}
# Compatibility alias for older Den builds; current den-api derives it from DEN_BASE_URL.
BETTER_AUTH_URL: {{ .Values.config.public.webOrigin | quote }}
{{ end }}
{{ if .Values.config.public.mcpResourceUrl }}
DEN_MCP_RESOURCE_URL: {{ .Values.config.public.mcpResourceUrl | quote }}
{{ end }}
# Extra MCP resource URLs beyond the DEN_API_PUBLIC_URL API origin and web-app defaults.
{{ if .Values.config.public.mcpAdditionalResources }}
DEN_MCP_ADDITIONAL_RESOURCES: {{ .Values.config.public.mcpAdditionalResources | quote }}
{{ end }}
DEN_MCP_CLAIM_NAMESPACE: {{ .Values.config.public.mcpClaimNamespace | quote }}
{{ if .Values.config.public.betterAuthTrustedOrigins }}
DEN_BETTER_AUTH_TRUSTED_ORIGINS: {{ .Values.config.public.betterAuthTrustedOrigins | quote }}
{{ end }}
{{ if .Values.config.public.betterAuthCookieDomain }}
DEN_BETTER_AUTH_COOKIE_DOMAIN: {{ .Values.config.public.betterAuthCookieDomain | quote }}
{{ end }}
{{ if .Values.config.public.webAppHosts }}
DEN_WEB_APP_HOSTS: {{ .Values.config.public.webAppHosts | quote }}
{{ end }}
DEN_BOOTSTRAP_ADMIN_EMAILS: {{ .Values.config.public.bootstrapAdminEmails | quote }}
DEN_INSTALL_LINKS_GATING_ENABLED: {{ .Values.config.public.installLinksGatingEnabled | quote }}
DEN_AUTOMATIONS_ENABLED: {{ .Values.config.public.automationsEnabled | quote }}
DEN_DASHBOARDS_ENABLED: {{ .Values.config.public.dashboardsEnabled | quote }}
DEN_OPENWORK_WEB_ENABLED: {{ .Values.config.public.openworkWebEnabled | quote }}
DEN_AUTOMATIONS_RUNTIME_ENABLED: {{ .Values.config.public.automationsRuntimeEnabled | quote }}
DEN_GENERATED_ARTIFACT_VIEWS_ENABLED: {{ .Values.config.public.generatedArtifactViewsEnabled | quote }}
DEN_CONNECT_LINK_MODE: {{ .Values.config.public.connectLinkMode | quote }}
{{ if .Values.config.public.connectLinkKeyId }}
DEN_CONNECT_LINK_KEY_ID: {{ .Values.config.public.connectLinkKeyId | quote }}
{{ end }}
{{ if .Values.config.public.corsOrigins }}
CORS_ORIGINS: {{ .Values.config.public.corsOrigins | quote }}
DEN_CORS_ORIGINS: {{ .Values.config.public.corsOrigins | quote }}
{{ end }}
{{ if .Values.config.public.apiOrigin }}
DEN_API_PUBLIC_URL: {{ .Values.config.public.apiOrigin | quote }}
{{ end }}
{{ if .Values.config.public.desktopDenBaseUrl }}
DEN_DESKTOP_DEN_BASE_URL: {{ .Values.config.public.desktopDenBaseUrl | quote }}
{{ end }}
{{ if .Values.config.public.installerReleaseTag }}
OPENWORK_INSTALLER_RELEASE_TAG: {{ .Values.config.public.installerReleaseTag | quote }}
{{ end }}
{{ if .Values.config.public.installerReleaseRepo }}
OPENWORK_INSTALLER_RELEASE_REPO: {{ .Values.config.public.installerReleaseRepo | quote }}
{{ end }}
PROVISIONER_MODE: {{ .Values.config.provisioner.mode | quote }}
WORKER_PROVISIONING_RECONCILE_INTERVAL_MS: {{ .Values.config.provisioner.reconcileIntervalMs | quote }}
WORKER_PROVISIONING_RECONCILE_STALE_MS: {{ .Values.config.provisioner.reconcileStaleMs | quote }}
WORKER_PROVISIONING_RECONCILE_BATCH_SIZE: {{ .Values.config.provisioner.reconcileBatchSize | quote }}
WORKER_URL_TEMPLATE: {{ .Values.config.provisioner.workerUrlTemplate | quote }}
{{ if or .Values.inference.enabled .Values.config.internal.inferenceProxyBaseUrl }}
INFERENCE_PROXY_BASE_URL: {{ include "openwork-ee.inferenceInternalUrl" . | quote }}
{{ end }}
POLAR_FEATURE_GATE_ENABLED: {{ .Values.config.polar.featureGateEnabled | quote }}
DAYTONA_SIGNED_PREVIEW_EXPIRES_SECONDS: {{ .Values.config.daytona.signedPreviewExpiresSeconds | quote }}
DEN_API_BASE: {{ include "openwork-ee.denApiInternalUrl" . | quote }}
DEN_AUTH_FALLBACK_BASE: {{ include "openwork-ee.authFallbackInternalUrl" . | quote }}
DEN_AUTH_ORIGIN: {{ .Values.config.public.webOrigin | quote }}
DEN_WEB_PUBLIC_ORIGIN: {{ .Values.config.public.webOrigin | quote }}
DEN_WEB_OPENWORK_AUTH_CALLBACK_URL: {{ .Values.config.public.authCallbackUrl | quote }}
{{ with .Values.config.polar.apiBase }}
POLAR_API_BASE: {{ . | quote }}
{{ end }}
{{ with .Values.config.polar.productId }}
POLAR_PRODUCT_ID: {{ . | quote }}
{{ end }}
{{ with .Values.config.polar.benefitId }}
POLAR_BENEFIT_ID: {{ . | quote }}
{{ end }}
{{ with .Values.config.polar.successUrl }}
POLAR_SUCCESS_URL: {{ . | quote }}
{{ end }}
{{ with .Values.config.polar.returnUrl }}
POLAR_RETURN_URL: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.apiUrl }}
DAYTONA_API_URL: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.target }}
DAYTONA_TARGET: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.snapshot }}
DAYTONA_SNAPSHOT: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.sandboxImage }}
DAYTONA_SANDBOX_IMAGE: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.sandboxCpu }}
DAYTONA_SANDBOX_CPU: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.sandboxMemory }}
DAYTONA_SANDBOX_MEMORY: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.sandboxDisk }}
DAYTONA_SANDBOX_DISK: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.sandboxPublic }}
DAYTONA_SANDBOX_PUBLIC: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.sandboxAutoStopInterval }}
DAYTONA_SANDBOX_AUTO_STOP_INTERVAL: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.sandboxAutoArchiveInterval }}
DAYTONA_SANDBOX_AUTO_ARCHIVE_INTERVAL: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.sandboxAutoDeleteInterval }}
DAYTONA_SANDBOX_AUTO_DELETE_INTERVAL: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.sandboxNamePrefix }}
DAYTONA_SANDBOX_NAME_PREFIX: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.sharedVolumeName }}
DAYTONA_SHARED_VOLUME_NAME: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.volumeNamePrefix }}
DAYTONA_VOLUME_NAME_PREFIX: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.workspaceMountPath }}
DAYTONA_WORKSPACE_MOUNT_PATH: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.dataMountPath }}
DAYTONA_DATA_MOUNT_PATH: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.runtimeWorkspacePath }}
DAYTONA_RUNTIME_WORKSPACE_PATH: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.runtimeDataPath }}
DAYTONA_RUNTIME_DATA_PATH: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.sidecarDir }}
DAYTONA_SIDECAR_DIR: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.openworkPort }}
DAYTONA_OPENWORK_PORT: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.opencodePort }}
DAYTONA_OPENCODE_PORT: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.createTimeoutSeconds }}
DAYTONA_CREATE_TIMEOUT_SECONDS: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.deleteTimeoutSeconds }}
DAYTONA_DELETE_TIMEOUT_SECONDS: {{ . | quote }}
{{ end }}
{{ with .Values.config.daytona.healthcheckTimeoutMs }}
DAYTONA_HEALTHCHECK_TIMEOUT_MS: {{ . | quote }}
{{ end }}
{{ with .Values.config.inference.openRouterWorkspaceId }}
OPENROUTER_WORKSPACE_ID: {{ . | quote }}
{{ end }}
{{ with .Values.config.inference.stripeInferencePriceId }}
STRIPE_INFERENCE_PRICE_ID: {{ . | quote }}
{{ end }}
{{ with .Values.config.inference.openRouterUpstreamUrl }}
OPENROUTER_UPSTREAM_URL: {{ . | quote }}
{{ end }}
{{ with .Values.config.inference.creditsPerDollar }}
INFERENCE_CREDITS_PER_DOLLAR: {{ . | quote }}
{{ end }}
{{ with .Values.config.public.openworkAppConnectUrl }}
DEN_WEB_OPENWORK_APP_CONNECT_URL: {{ . | quote }}
{{ end }}
{{ with .Values.config.public.openworkWebUrl }}
DEN_WEB_OPENWORK_WEB_URL: {{ . | quote }}
{{ end }}
{{ with .Values.config.web.posthogKey }}
DEN_WEB_POSTHOG_KEY: {{ . | quote }}
{{ end }}
{{ with .Values.config.web.posthogHost }}
DEN_WEB_POSTHOG_HOST: {{ . | quote }}
{{ end }}
@@ -0,0 +1,145 @@
{{- include "openwork-ee.customCa.validate" . }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "openwork-ee.denApiServiceName" . }}
labels:
{{- include "openwork-ee.componentLabels" (dict "root" . "component" "den-api") | nindent 4 }}
{{- with .Values.denApi.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.denApi.service.type }}
{{- with .Values.denApi.service.loadBalancerClass }}
loadBalancerClass: {{ . | quote }}
{{- end }}
{{- with .Values.denApi.service.loadBalancerSourceRanges }}
loadBalancerSourceRanges:
{{- toYaml . | nindent 4 }}
{{- end }}
ports:
- name: http
port: {{ .Values.denApi.service.port }}
targetPort: http
selector:
{{- include "openwork-ee.componentSelectorLabels" (dict "root" . "component" "den-api") | nindent 4 }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "openwork-ee.fullname" . }}-den-api
labels:
{{- include "openwork-ee.componentLabels" (dict "root" . "component" "den-api") | nindent 4 }}
spec:
replicas: {{ .Values.denApi.replicaCount }}
selector:
matchLabels:
{{- include "openwork-ee.componentSelectorLabels" (dict "root" . "component" "den-api") | nindent 6 }}
template:
metadata:
labels:
{{- include "openwork-ee.componentSelectorLabels" (dict "root" . "component" "den-api") | nindent 8 }}
{{- with .Values.denApi.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- with .Values.denApi.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.installerArtifacts.enabled }}
{{- if and .Values.installerArtifacts.existingClaim .Values.installerArtifacts.hostPath }}
{{- fail "installerArtifacts.existingClaim and installerArtifacts.hostPath are mutually exclusive" }}
{{- end }}
{{- if not (or .Values.installerArtifacts.existingClaim .Values.installerArtifacts.hostPath) }}
{{- fail "installerArtifacts.existingClaim or installerArtifacts.hostPath is required when installerArtifacts.enabled=true" }}
{{- end }}
{{- end }}
{{- if or .Values.installerArtifacts.enabled .Values.customCa.enabled }}
volumes:
{{- if .Values.installerArtifacts.enabled }}
- name: installer-artifacts
{{- if .Values.installerArtifacts.existingClaim }}
persistentVolumeClaim:
claimName: {{ .Values.installerArtifacts.existingClaim | quote }}
{{- else }}
hostPath:
path: {{ .Values.installerArtifacts.hostPath | quote }}
type: Directory
{{- end }}
{{- end }}
{{- if .Values.customCa.enabled }}
{{- include "openwork-ee.customCa.volume" . | nindent 8 }}
{{- end }}
{{- end }}
containers:
- name: den-api
image: "{{ .Values.denApi.image.repository }}:{{ default .Values.image.tag .Values.denApi.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.denApi.containerPort }}
{{- if or .Values.installerArtifacts.enabled .Values.customCa.enabled }}
volumeMounts:
{{- if .Values.installerArtifacts.enabled }}
- name: installer-artifacts
mountPath: {{ .Values.installerArtifacts.mountPath | quote }}
readOnly: true
{{- end }}
{{- if .Values.customCa.enabled }}
{{- include "openwork-ee.customCa.volumeMount" . | nindent 12 }}
{{- end }}
{{- end }}
envFrom:
- configMapRef:
name: {{ include "openwork-ee.configName" . }}
- secretRef:
name: {{ include "openwork-ee.secretName" . }}
env:
- name: PORT
value: {{ .Values.denApi.containerPort | quote }}
{{- if not (hasKey .Values.denApi.env "NODE_OPTIONS") }}
# Keep this as a direct value so upgrades from legacy denApi.env.NODE_OPTIONS
# do not leave both value and valueFrom in Kubernetes' strategic merge patch.
- name: NODE_OPTIONS
value: {{ .Values.config.denApiNodeOptions | quote }}
# Explicitly clear the valueFrom emitted by chart 0.17.24 during upgrades.
valueFrom: null
{{- end }}
{{- if .Values.installerArtifacts.enabled }}
- name: OPENWORK_INSTALLER_ARTIFACTS_DIR
value: {{ .Values.installerArtifacts.mountPath | quote }}
{{- end }}
{{- if .Values.customCa.enabled }}
{{- include "openwork-ee.customCa.env" . | nindent 12 }}
{{- end }}
{{- if eq (include "openwork-ee.allowPrivateMcpUrls" .) "1" }}
- name: DEN_ALLOW_PRIVATE_MCP_URLS
value: "1"
{{- end }}
{{- include "openwork-ee.observabilityEnv" (dict "root" . "serviceName" .Values.observability.serviceNames.denApi) | nindent 12 }}
{{- range $key, $value := .Values.denApi.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
livenessProbe:
httpGet:
path: /health
port: http
{{- toYaml .Values.denApi.probes.liveness | nindent 12 }}
readinessProbe:
httpGet:
path: /ready
port: http
{{- toYaml .Values.denApi.probes.readiness | nindent 12 }}
{{- with .Values.denApi.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
@@ -0,0 +1,101 @@
{{- include "openwork-ee.customCa.validate" . }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "openwork-ee.denWebServiceName" . }}
labels:
{{- include "openwork-ee.componentLabels" (dict "root" . "component" "den-web") | nindent 4 }}
{{- with .Values.denWeb.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.denWeb.service.type }}
{{- with .Values.denWeb.service.loadBalancerClass }}
loadBalancerClass: {{ . | quote }}
{{- end }}
{{- with .Values.denWeb.service.loadBalancerSourceRanges }}
loadBalancerSourceRanges:
{{- toYaml . | nindent 4 }}
{{- end }}
ports:
- name: http
port: {{ .Values.denWeb.service.port }}
targetPort: http
selector:
{{- include "openwork-ee.componentSelectorLabels" (dict "root" . "component" "den-web") | nindent 4 }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "openwork-ee.fullname" . }}-den-web
labels:
{{- include "openwork-ee.componentLabels" (dict "root" . "component" "den-web") | nindent 4 }}
spec:
replicas: {{ .Values.denWeb.replicaCount }}
selector:
matchLabels:
{{- include "openwork-ee.componentSelectorLabels" (dict "root" . "component" "den-web") | nindent 6 }}
template:
metadata:
labels:
{{- include "openwork-ee.componentSelectorLabels" (dict "root" . "component" "den-web") | nindent 8 }}
{{- with .Values.denWeb.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- with .Values.denWeb.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.customCa.enabled }}
volumes:
{{- include "openwork-ee.customCa.volume" . | nindent 8 }}
{{- end }}
containers:
- name: den-web
image: "{{ .Values.denWeb.image.repository }}:{{ default .Values.image.tag .Values.denWeb.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.denWeb.containerPort }}
{{- if .Values.customCa.enabled }}
volumeMounts:
{{- include "openwork-ee.customCa.volumeMount" . | nindent 12 }}
{{- end }}
envFrom:
- configMapRef:
name: {{ include "openwork-ee.configName" . }}
- secretRef:
name: {{ include "openwork-ee.secretName" . }}
env:
- name: PORT
value: {{ .Values.denWeb.containerPort | quote }}
{{- if .Values.customCa.enabled }}
{{- include "openwork-ee.customCa.env" . | nindent 12 }}
{{- end }}
{{- include "openwork-ee.observabilityEnv" (dict "root" . "serviceName" .Values.observability.serviceNames.denWeb) | nindent 12 }}
{{- range $key, $value := .Values.denWeb.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
livenessProbe:
httpGet:
path: /api/health
port: http
{{- toYaml .Values.denWeb.probes.liveness | nindent 12 }}
readinessProbe:
httpGet:
path: /api/ready
port: http
{{- toYaml .Values.denWeb.probes.readiness | nindent 12 }}
{{- with .Values.denWeb.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
@@ -0,0 +1,102 @@
{{- include "openwork-ee.customCa.validate" . }}
{{- if .Values.inference.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "openwork-ee.inferenceServiceName" . }}
labels:
{{- include "openwork-ee.componentLabels" (dict "root" . "component" "inference") | nindent 4 }}
{{- with .Values.inference.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.inference.service.type }}
{{- with .Values.inference.service.loadBalancerClass }}
loadBalancerClass: {{ . | quote }}
{{- end }}
{{- with .Values.inference.service.loadBalancerSourceRanges }}
loadBalancerSourceRanges:
{{- toYaml . | nindent 4 }}
{{- end }}
ports:
- name: http
port: {{ .Values.inference.service.port }}
targetPort: http
selector:
{{- include "openwork-ee.componentSelectorLabels" (dict "root" . "component" "inference") | nindent 4 }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "openwork-ee.fullname" . }}-inference
labels:
{{- include "openwork-ee.componentLabels" (dict "root" . "component" "inference") | nindent 4 }}
spec:
replicas: {{ .Values.inference.replicaCount }}
selector:
matchLabels:
{{- include "openwork-ee.componentSelectorLabels" (dict "root" . "component" "inference") | nindent 6 }}
template:
metadata:
labels:
{{- include "openwork-ee.componentSelectorLabels" (dict "root" . "component" "inference") | nindent 8 }}
{{- with .Values.inference.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- with .Values.inference.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.customCa.enabled }}
volumes:
{{- include "openwork-ee.customCa.volume" . | nindent 8 }}
{{- end }}
containers:
- name: inference
image: "{{ .Values.inference.image.repository }}:{{ default .Values.image.tag .Values.inference.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.inference.containerPort }}
{{- if .Values.customCa.enabled }}
volumeMounts:
{{- include "openwork-ee.customCa.volumeMount" . | nindent 12 }}
{{- end }}
envFrom:
- configMapRef:
name: {{ include "openwork-ee.configName" . }}
- secretRef:
name: {{ include "openwork-ee.secretName" . }}
env:
- name: PORT
value: {{ .Values.inference.containerPort | quote }}
{{- if .Values.customCa.enabled }}
{{- include "openwork-ee.customCa.env" . | nindent 12 }}
{{- end }}
{{- range $key, $value := .Values.inference.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
livenessProbe:
httpGet:
path: /health
port: http
{{- toYaml .Values.inference.probes.liveness | nindent 12 }}
readinessProbe:
httpGet:
path: /ready
port: http
{{- toYaml .Values.inference.probes.readiness | nindent 12 }}
{{- with .Values.inference.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- end }}
@@ -0,0 +1,43 @@
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "openwork-ee.fullname" . }}
labels:
{{- include "openwork-ee.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- with .Values.ingress.tls }}
tls:
{{- toYaml . | nindent 4 }}
{{- end }}
rules:
- host: {{ .Values.ingress.web.host | quote }}
http:
paths:
- path: {{ .Values.ingress.web.path }}
pathType: {{ .Values.ingress.web.pathType }}
backend:
service:
name: {{ include "openwork-ee.denWebServiceName" . }}
port:
name: http
{{- if .Values.ingress.api.enabled }}
- host: {{ .Values.ingress.api.host | quote }}
http:
paths:
- path: {{ .Values.ingress.api.path }}
pathType: {{ .Values.ingress.api.pathType }}
backend:
service:
name: {{ include "openwork-ee.denApiServiceName" . }}
port:
name: http
{{- end }}
{{- end }}
@@ -0,0 +1,78 @@
{{- include "openwork-ee.customCa.validate" . }}
{{- if .Values.migrations.enabled }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "openwork-ee.fullname" . }}-migrate
labels:
{{- include "openwork-ee.componentLabels" (dict "root" . "component" "migration") | nindent 4 }}
{{- if .Values.migrations.hook }}
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-weight": "-5"
{{- with .Values.migrations.hookDeletePolicy }}
"helm.sh/hook-delete-policy": {{ . | quote }}
{{- end }}
{{- end }}
spec:
backoffLimit: {{ .Values.migrations.backoffLimit }}
activeDeadlineSeconds: {{ .Values.migrations.activeDeadlineSeconds }}
template:
metadata:
labels:
{{- include "openwork-ee.componentSelectorLabels" (dict "root" . "component" "migration") | nindent 8 }}
{{- with .Values.migrations.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
restartPolicy: Never
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.customCa.enabled }}
volumes:
{{- include "openwork-ee.customCa.volume" . | nindent 8 }}
{{- end }}
containers:
- name: migrate
image: "{{ .Values.denApi.image.repository }}:{{ default .Values.image.tag .Values.denApi.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if .Values.customCa.enabled }}
volumeMounts:
{{- include "openwork-ee.customCa.volumeMount" . | nindent 12 }}
{{- end }}
command:
{{- toYaml .Values.migrations.command | nindent 12 }}
args:
{{- toYaml .Values.migrations.args | nindent 12 }}
env:
- name: DB_MODE
value: {{ .Values.config.databaseMode | quote }}
- name: DATABASE_URL
{{- if .Values.secret.create }}
value: {{ .Values.secret.values.databaseUrl | quote }}
{{- else }}
valueFrom:
secretKeyRef:
name: {{ include "openwork-ee.secretName" . }}
key: {{ .Values.secret.keys.databaseUrl }}
{{- end }}
- name: DEN_DB_ENCRYPTION_KEY
{{- if .Values.secret.create }}
value: {{ .Values.secret.values.denDbEncryptionKey | quote }}
{{- else }}
valueFrom:
secretKeyRef:
name: {{ include "openwork-ee.secretName" . }}
key: {{ .Values.secret.keys.denDbEncryptionKey }}
{{- end }}
{{- if .Values.customCa.enabled }}
{{- include "openwork-ee.customCa.env" . | nindent 12 }}
{{- end }}
{{- with .Values.migrations.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- end }}
@@ -0,0 +1,30 @@
{{- if .Values.secret.create }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "openwork-ee.secretName" . }}
labels:
{{- include "openwork-ee.labels" . | nindent 4 }}
type: Opaque
stringData:
{{ .Values.secret.keys.databaseUrl }}: {{ .Values.secret.values.databaseUrl | quote }}
{{ .Values.secret.keys.databaseRedisUrl }}: {{ .Values.secret.values.databaseRedisUrl | quote }}
{{ .Values.secret.keys.betterAuthSecret }}: {{ .Values.secret.values.betterAuthSecret | quote }}
{{ .Values.secret.keys.denDbEncryptionKey }}: {{ .Values.secret.values.denDbEncryptionKey | quote }}
{{ .Values.secret.keys.daytonaApiKey }}: {{ .Values.secret.values.daytonaApiKey | quote }}
{{ .Values.secret.keys.polarAccessToken }}: {{ .Values.secret.values.polarAccessToken | quote }}
{{ .Values.secret.keys.openRouterManagementApiKey }}: {{ .Values.secret.values.openRouterManagementApiKey | quote }}
{{ .Values.secret.keys.inferenceAdminToken }}: {{ .Values.secret.values.inferenceAdminToken | quote }}
{{ .Values.secret.keys.inferenceWebhookSecret }}: {{ .Values.secret.values.inferenceWebhookSecret | quote }}
{{ .Values.secret.keys.emailFrom }}: {{ .Values.secret.values.emailFrom | quote }}
{{ .Values.secret.keys.smtpHost }}: {{ .Values.secret.values.smtpHost | quote }}
{{ .Values.secret.keys.smtpPort }}: {{ .Values.secret.values.smtpPort | quote }}
{{ .Values.secret.keys.smtpUser }}: {{ .Values.secret.values.smtpUser | quote }}
{{ .Values.secret.keys.smtpPass }}: {{ .Values.secret.values.smtpPass | quote }}
{{ .Values.secret.keys.smtpSecure }}: {{ .Values.secret.values.smtpSecure | quote }}
{{ .Values.secret.keys.githubConnectorAppClientSecret }}: {{ .Values.secret.values.githubConnectorAppClientSecret | quote }}
{{ .Values.secret.keys.githubConnectorAppPrivateKey }}: {{ .Values.secret.values.githubConnectorAppPrivateKey | quote }}
{{ .Values.secret.keys.githubConnectorAppWebhookSecret }}: {{ .Values.secret.values.githubConnectorAppWebhookSecret | quote }}
{{ .Values.secret.keys.connectLinkPrivateKey }}: {{ .Values.secret.values.connectLinkPrivateKey | quote }}
{{ .Values.secret.keys.initialAdminBootstrapCode }}: {{ .Values.secret.values.initialAdminBootstrapCode | quote }}
{{- end }}
@@ -0,0 +1,182 @@
{{- include "openwork-ee.customCa.validate" . }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "openwork-ee.fullname" . }}-env-probe
labels:
{{- include "openwork-ee.componentLabels" (dict "root" . "component" "env-probe") | nindent 4 }}
annotations:
"helm.sh/hook": test
"helm.sh/hook-delete-policy": before-hook-creation
spec:
backoffLimit: 0
activeDeadlineSeconds: 120
template:
metadata:
labels:
{{- include "openwork-ee.componentSelectorLabels" (dict "root" . "component" "env-probe") | nindent 8 }}
spec:
restartPolicy: Never
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.customCa.enabled }}
volumes:
{{- include "openwork-ee.customCa.volume" . | nindent 8 }}
{{- end }}
containers:
- name: env-probe
image: "{{ .Values.denApi.image.repository }}:{{ default .Values.image.tag .Values.denApi.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if .Values.customCa.enabled }}
volumeMounts:
{{- include "openwork-ee.customCa.volumeMount" . | nindent 12 }}
{{- end }}
command:
- node
args:
- -e
- |
const fs = require("node:fs");
const tls = require("node:tls");
const expected = new Map([
["DB_MODE", process.env.OPENWORK_ENV_PROBE_EXPECTED_DB_MODE],
["DEN_ORG_MODE", process.env.OPENWORK_ENV_PROBE_EXPECTED_DEN_ORG_MODE],
["PROVISIONER_MODE", process.env.OPENWORK_ENV_PROBE_EXPECTED_PROVISIONER_MODE],
["OPENWORK_DEV_MODE", process.env.OPENWORK_ENV_PROBE_EXPECTED_OPENWORK_DEV_MODE],
["DEN_BASE_URL", process.env.OPENWORK_ENV_PROBE_EXPECTED_DEN_BASE_URL],
["DEN_AUTH_ORIGIN", process.env.OPENWORK_ENV_PROBE_EXPECTED_DEN_AUTH_ORIGIN],
["PORT", process.env.OPENWORK_ENV_PROBE_EXPECTED_PORT],
["NODE_OPTIONS", process.env.OPENWORK_ENV_PROBE_EXPECTED_NODE_OPTIONS],
["DEN_API_NODE_OPTIONS", process.env.OPENWORK_ENV_PROBE_EXPECTED_NODE_OPTIONS],
]);
const required = [
"DATABASE_URL",
"DEN_DB_ENCRYPTION_KEY",
"BETTER_AUTH_SECRET",
"DEN_BASE_URL",
"DB_MODE",
"DEN_ORG_MODE",
"PROVISIONER_MODE",
"DEN_API_BASE",
"DEN_AUTH_FALLBACK_BASE",
"DEN_AUTH_ORIGIN",
"OPENWORK_DEV_MODE",
"PORT",
"NODE_OPTIONS",
];
const secretPattern = /(SECRET|PASSWORD|PRIVATE|TOKEN|KEY|DATABASE_URL|BOOTSTRAP_CODE|SHA256)/;
const failures = [];
function compactPem(value) {
return value.replace(/\s+/g, "");
}
function display(name, value) {
if (value === undefined) return "<missing>";
if (secretPattern.test(name)) return value ? "<set>" : "<empty>";
return JSON.stringify(value);
}
for (const name of required) {
if (process.env[name] === undefined) {
failures.push(`${name}: expected present, actual <missing>`);
}
}
for (const [name, expectedValue] of expected) {
if (expectedValue === undefined) continue;
const actual = process.env[name];
if (actual !== expectedValue) {
failures.push(`${name}: expected ${display(name, expectedValue)}, actual ${display(name, actual)}`);
}
}
if (process.env.OPENWORK_ENV_PROBE_EXPECTED_CUSTOM_CA === "1") {
const expectedCaPath = process.env.OPENWORK_ENV_PROBE_EXPECTED_NODE_EXTRA_CA_CERTS;
if (process.env.NODE_EXTRA_CA_CERTS !== expectedCaPath) {
failures.push(`NODE_EXTRA_CA_CERTS: expected ${display("NODE_EXTRA_CA_CERTS", expectedCaPath)}, actual ${display("NODE_EXTRA_CA_CERTS", process.env.NODE_EXTRA_CA_CERTS)}`);
} else {
try {
const bundle = fs.readFileSync(expectedCaPath, "utf8");
const certs = bundle.match(/-----BEGIN CERTIFICATE-----[\s\S]*?-----END CERTIFICATE-----/g) || [];
if (certs.length === 0) {
failures.push(`NODE_EXTRA_CA_CERTS: ${expectedCaPath} did not contain a PEM certificate`);
} else if (typeof tls.getCACertificates !== "function") {
failures.push("NODE_EXTRA_CA_CERTS: node does not expose tls.getCACertificates; cannot prove runtime trust");
} else {
const extra = tls.getCACertificates("extra").map(compactPem);
const trusted = certs.some((cert) => extra.includes(compactPem(cert)));
if (!trusted) {
failures.push(`NODE_EXTRA_CA_CERTS: ${expectedCaPath} was mounted but did not appear in node's extra CA trust store`);
}
}
} catch (error) {
failures.push(`NODE_EXTRA_CA_CERTS: could not read ${expectedCaPath}: ${error instanceof Error ? error.message : String(error)}`);
}
}
}
if (failures.length > 0) {
console.error("OpenWork Helm env probe failed:");
for (const failure of failures) console.error(`- ${failure}`);
console.error("Observed runtime env:");
for (const name of [...required, "DEN_API_NODE_OPTIONS", "NODE_EXTRA_CA_CERTS"].sort()) {
console.error(` ${name}: ${display(name, process.env[name])}`);
}
process.exit(1);
}
console.log("OpenWork Helm env probe passed.");
console.log(`DEN_ORG_MODE=${process.env.DEN_ORG_MODE}; PROVISIONER_MODE=${process.env.PROVISIONER_MODE}; NODE_OPTIONS=${JSON.stringify(process.env.NODE_OPTIONS || "")}`);
if (process.env.NODE_EXTRA_CA_CERTS) console.log(`NODE_EXTRA_CA_CERTS=${process.env.NODE_EXTRA_CA_CERTS} is loaded by node.`);
envFrom:
- configMapRef:
name: {{ include "openwork-ee.configName" . }}
- secretRef:
name: {{ include "openwork-ee.secretName" . }}
env:
- name: PORT
value: {{ .Values.denApi.containerPort | quote }}
{{- if not (hasKey .Values.denApi.env "NODE_OPTIONS") }}
- name: NODE_OPTIONS
value: {{ .Values.config.denApiNodeOptions | quote }}
{{- end }}
{{- if .Values.installerArtifacts.enabled }}
- name: OPENWORK_INSTALLER_ARTIFACTS_DIR
value: {{ .Values.installerArtifacts.mountPath | quote }}
{{- end }}
{{- if .Values.customCa.enabled }}
{{- include "openwork-ee.customCa.env" . | nindent 12 }}
{{- end }}
{{- if eq (include "openwork-ee.allowPrivateMcpUrls" .) "1" }}
- name: DEN_ALLOW_PRIVATE_MCP_URLS
value: "1"
{{- end }}
{{- range $key, $value := .Values.denApi.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
- name: OPENWORK_ENV_PROBE_EXPECTED_DB_MODE
value: {{ .Values.config.databaseMode | quote }}
- name: OPENWORK_ENV_PROBE_EXPECTED_DEN_ORG_MODE
value: {{ .Values.config.tenancy.mode | quote }}
- name: OPENWORK_ENV_PROBE_EXPECTED_PROVISIONER_MODE
value: {{ .Values.config.provisioner.mode | quote }}
- name: OPENWORK_ENV_PROBE_EXPECTED_OPENWORK_DEV_MODE
value: {{ .Values.config.openworkDevMode | quote }}
- name: OPENWORK_ENV_PROBE_EXPECTED_DEN_BASE_URL
value: {{ .Values.config.public.webOrigin | quote }}
- name: OPENWORK_ENV_PROBE_EXPECTED_DEN_AUTH_ORIGIN
value: {{ .Values.config.public.webOrigin | quote }}
- name: OPENWORK_ENV_PROBE_EXPECTED_PORT
value: {{ .Values.denApi.containerPort | quote }}
- name: OPENWORK_ENV_PROBE_EXPECTED_NODE_OPTIONS
value: {{ if hasKey .Values.denApi.env "NODE_OPTIONS" }}{{ index .Values.denApi.env "NODE_OPTIONS" | quote }}{{ else }}{{ .Values.config.denApiNodeOptions | quote }}{{ end }}
- name: OPENWORK_ENV_PROBE_EXPECTED_CUSTOM_CA
value: {{ ternary "1" "0" .Values.customCa.enabled | quote }}
{{- if .Values.customCa.enabled }}
- name: OPENWORK_ENV_PROBE_EXPECTED_NODE_EXTRA_CA_CERTS
value: {{ include "openwork-ee.customCa.filePath" . | quote }}
{{- end }}