Files
call-center/deployment/helm/templates/services.yaml
T

405 lines
16 KiB
YAML

{{- range $name, $svc := .Values.services }}
{{- $databaseUrl := $.Values.global.databaseUrl | default "" }}
{{- $schemaManagementMode := $.Values.global.schemaManagementMode | default "legacy" }}
{{- $isGateway := default false $svc.gateway }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ $name }}
namespace: {{ $.Values.namespace }}
spec:
replicas: {{ $svc.replicas }}
selector:
matchLabels:
app: {{ $name }}
template:
metadata:
labels:
app: {{ $name }}
spec:
terminationGracePeriodSeconds: 30
{{- if $.Values.global.runtimeClass }}
runtimeClassName: {{ $.Values.global.runtimeClass }}
{{- end }}
{{- if gt (int $svc.replicas) 1 }}
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
app: {{ $name }}
{{- end }}
containers:
- name: app
image: "{{ $.Values.image.repository }}:{{ $.Values.image.tag }}"
imagePullPolicy: {{ $.Values.global.imagePullPolicy }}
env:
- name: APP_MODULE
value: "{{ $svc.module }}"
- name: CC_DATA_DIR
value: /var/lib/mvp-cc/data
- name: APP_TOKEN_SECRET
value: "{{ $.Values.auth.appTokenSecret }}"
- name: APP_TOKEN_TTL_SECONDS
value: "{{ $.Values.auth.appTokenTtlSeconds }}"
- name: ALLOW_LEGACY_HEADER_AUTH
value: "{{ $.Values.auth.allowLegacyHeaderAuth }}"
{{- if or $.Values.profiles.scale500.enabled $databaseUrl }}
- name: DATABASE_URL
value: "{{ if $.Values.profiles.scale500.enabled }}{{ required "global.databaseUrl is required when profiles.scale500.enabled=true" $.Values.global.databaseUrl }}{{ else }}{{ $databaseUrl }}{{ end }}"
{{- end }}
- name: SCHEMA_MANAGEMENT_MODE
value: "{{ $schemaManagementMode }}"
- name: DB_POOL_SIZE
value: "{{ $.Values.db.poolSize }}"
- name: DB_MAX_OVERFLOW
value: "{{ $.Values.db.maxOverflow }}"
- name: DB_POOL_TIMEOUT_SECONDS
value: "{{ $.Values.db.poolTimeoutSeconds }}"
- name: DB_POOL_RECYCLE_SECONDS
value: "{{ $.Values.db.poolRecycleSeconds }}"
- name: EVENT_BUS_ENABLED
value: "{{ $.Values.eventBus.enabled }}"
- name: EVENT_BUS_URL
value: "{{ $.Values.eventBus.url }}"
- name: EVENT_BUS_EXCHANGE
value: "{{ $.Values.eventBus.exchange }}"
- name: EVENT_BUS_DISPATCH_BATCH_SIZE
value: "{{ $.Values.eventBus.dispatchBatchSize }}"
- name: EVENT_BUS_MAX_ATTEMPTS
value: "{{ $.Values.eventBus.maxAttempts }}"
- name: EVENT_BUS_POLL_INTERVAL_SECONDS
value: "{{ $.Values.eventBus.pollIntervalSeconds }}"
- name: EVENT_BUS_CONSUMER_ENABLED
value: "{{ $.Values.eventBus.consumerEnabled }}"
- name: EVENT_BUS_AUDIT_QUEUE
value: "{{ $.Values.eventBus.auditQueue }}"
- name: EVENT_BUS_REPORTING_QUEUE
value: "{{ $.Values.eventBus.reportingQueue }}"
{{- if eq $name "asterisk-bridge-service" }}
- name: ASTERISK_BRIDGE_ENABLED
value: "{{ $.Values.asteriskBridge.enabled }}"
- name: ASTERISK_AMI_HOST
value: "{{ $.Values.asteriskBridge.amiHost }}"
- name: ASTERISK_AMI_PORT
value: "{{ $.Values.asteriskBridge.amiPort }}"
- name: ASTERISK_AMI_USERNAME
value: "{{ $.Values.asteriskBridge.amiUsername }}"
- name: ASTERISK_AMI_SECRET
value: "{{ $.Values.asteriskBridge.amiSecret }}"
- name: ASTERISK_AMI_EVENT_PREFIX
value: "{{ $.Values.asteriskBridge.amiEventPrefix }}"
- name: ASTERISK_QUEUE_MAP_JSON
value: '{{ $.Values.asteriskBridge.queueMapJson }}'
- name: ASTERISK_SFTP_HOST
value: "{{ $.Values.asteriskBridge.sftpHost }}"
- name: ASTERISK_SFTP_PORT
value: "{{ $.Values.asteriskBridge.sftpPort }}"
- name: ASTERISK_SFTP_USERNAME
value: "{{ $.Values.asteriskBridge.sftpUsername }}"
- name: ASTERISK_SFTP_PASSWORD
value: "{{ $.Values.asteriskBridge.sftpPassword }}"
- name: ASTERISK_SFTP_BASE_PATH
value: "{{ $.Values.asteriskBridge.sftpBasePath }}"
- name: ASTERISK_BRIDGE_POLL_INTERVAL_SECONDS
value: "{{ $.Values.asteriskBridge.pollIntervalSeconds }}"
- name: ASTERISK_BRIDGE_AUTH_MODE
value: "{{ $.Values.asteriskBridge.authMode }}"
- name: ASTERISK_BRIDGE_AUTH_FALLBACK_LEGACY
value: "{{ $.Values.asteriskBridge.authFallbackLegacy }}"
- name: ASTERISK_BRIDGE_AUTH_SUBJECT
value: "{{ $.Values.asteriskBridge.authSubject }}"
- name: ASTERISK_BRIDGE_AUTH_USER
value: "{{ $.Values.asteriskBridge.authUser }}"
- name: ASTERISK_BRIDGE_AUTH_ROLE
value: "{{ $.Values.asteriskBridge.authRole }}"
- name: ASTERISK_BRIDGE_AUTH_TOKEN_TTL_SECONDS
value: "{{ $.Values.asteriskBridge.authTokenTtlSeconds }}"
- name: ASTERISK_IVR_FASTAGI_ENABLED
value: "{{ $.Values.asteriskBridge.ivrFastagiEnabled }}"
- name: ASTERISK_IVR_FASTAGI_HOST
value: "{{ $.Values.asteriskBridge.ivrFastagiHost }}"
- name: ASTERISK_IVR_FASTAGI_PORT
value: "{{ $.Values.asteriskBridge.ivrFastagiPort }}"
- name: ASTERISK_IVR_DTMF_TIMEOUT_SECONDS
value: "{{ $.Values.asteriskBridge.ivrDtmfTimeoutSeconds }}"
- name: ASTERISK_IVR_MAX_NO_INPUT_RETRIES
value: "{{ $.Values.asteriskBridge.ivrMaxNoInputRetries }}"
- name: ASTERISK_IVR_MAX_INVALID_RETRIES
value: "{{ $.Values.asteriskBridge.ivrMaxInvalidRetries }}"
- name: ASTERISK_IVR_CALL_LINK_WAIT_SECONDS
value: "{{ $.Values.asteriskBridge.ivrCallLinkWaitSeconds }}"
- name: ASTERISK_CALLCONTROL_ENABLED
value: "{{ $.Values.asteriskBridge.callcontrolEnabled }}"
- name: ASTERISK_CALLCONTROL_ACTION_TIMEOUT_SECONDS
value: "{{ $.Values.asteriskBridge.callcontrolActionTimeoutSeconds }}"
- name: ASTERISK_OPERATOR_EXTENSION_MAP_JSON
value: '{{ $.Values.asteriskBridge.operatorExtensionMapJson }}'
- name: ASTERISK_TRANSFER_TARGET_MAP_JSON
value: '{{ $.Values.asteriskBridge.transferTargetMapJson }}'
- name: ASTERISK_CALLCONTROL_CLAIM_CONTEXT
value: "{{ $.Values.asteriskBridge.claimContext }}"
- name: ASTERISK_CALLCONTROL_TRANSFER_CONTEXT
value: "{{ $.Values.asteriskBridge.transferContext }}"
- name: AI_VOICE_RUNTIME_SERVICE_URL
value: http://ai-voice-runtime-service:8000
- name: AI_VOICE_ENABLED
value: "{{ $.Values.voiceAI.enabled }}"
- name: AI_VOICE_QUEUE_CONFIG_JSON
value: '{{ $.Values.voiceAI.queueConfigJson }}'
- name: AI_VOICE_RUNTIME_TRUSTED_SERVICE_SUBJECTS
value: "{{ $.Values.voiceAI.runtimeTrustedServiceSubjects }}"
- name: INTERACTION_SERVICE_URL
value: http://interaction-service:8000
- name: VOICE_ADAPTER_SERVICE_URL
value: http://voice-adapter-service:8000
- name: RECORDING_SERVICE_URL
value: http://recording-service:8000
- name: IVR_SERVICE_URL
value: http://ivr-service:8000
{{- end }}
{{- if eq $name "ivr-service" }}
- name: IVR_RUNTIME_TRUSTED_SERVICE_SUBJECTS
value: "{{ $.Values.ivrRuntime.trustedServiceSubjects }}"
{{- end }}
{{- if eq $name "ai-orchestrator-service" }}
- name: INTERACTION_SERVICE_URL
value: http://interaction-service:8000
- name: TELEGRAM_ADAPTER_SERVICE_URL
value: http://telegram-adapter-service:8000
- name: AI_VOICE_MAX_CONTEXT_SEGMENTS
value: "{{ $.Values.voiceAI.maxContextSegments }}"
{{- end }}
{{- if eq $name "ai-voice-runtime-service" }}
- name: AI_ORCHESTRATOR_SERVICE_URL
value: http://ai-orchestrator-service:8000
- name: ASTERISK_BRIDGE_SERVICE_URL
value: http://asterisk-bridge-service:8000
- name: AI_VOICE_ASR_PROVIDER
value: "{{ $.Values.voiceAI.asrProvider }}"
- name: AI_VOICE_TTS_PROVIDER
value: "{{ $.Values.voiceAI.ttsProvider }}"
- name: AI_VOICE_AUDIOSOCKET_ENABLED
value: "{{ $.Values.voiceAI.audioSocketEnabled }}"
- name: AI_VOICE_AUDIOSOCKET_HOST
value: "{{ $.Values.voiceAI.audioSocketHost }}"
- name: AI_VOICE_AUDIOSOCKET_PORT
value: "{{ $.Values.voiceAI.audioSocketPort }}"
- name: AI_VOICE_ASR_MODEL
value: "{{ $.Values.voiceAI.asrModel }}"
- name: AI_VOICE_TTS_MODEL
value: "{{ $.Values.voiceAI.ttsModel }}"
- name: AI_VOICE_TTS_VOICE
value: "{{ $.Values.voiceAI.ttsVoice }}"
- name: AI_VOICE_TTS_CACHE_ENABLED
value: "{{ $.Values.voiceAI.ttsCacheEnabled }}"
- name: AI_VOICE_TTS_CACHE_DIR
value: "{{ $.Values.voiceAI.ttsCacheDir }}"
- name: AI_VOICE_VAD_MIN_SPEECH_MS
value: "{{ $.Values.voiceAI.vadMinSpeechMs }}"
- name: AI_VOICE_VAD_TRAILING_SILENCE_MS
value: "{{ $.Values.voiceAI.vadTrailingSilenceMs }}"
- name: AI_VOICE_TURN_MAX_MS
value: "{{ $.Values.voiceAI.turnMaxMs }}"
- name: AI_VOICE_MEDIA_IDLE_TIMEOUT_SECONDS
value: "{{ $.Values.voiceAI.mediaIdleTimeoutSeconds }}"
- name: AI_VOICE_HANDOFF_TIMEOUT_SECONDS
value: "{{ $.Values.voiceAI.handoffTimeoutSeconds }}"
{{- end }}
{{- if eq $name "recording-service" }}
- name: CC_RECORDINGS_DIR
value: /var/lib/mvp-cc/data/recordings
- name: RECORDING_MAX_BYTES
value: "26214400"
- name: RECORDING_IMPORT_TRUSTED_SERVICE_SUBJECTS
value: "{{ $.Values.recording.importTrustedServiceSubjects }}"
- name: RECORDING_IMPORT_ALLOW_ADMIN
value: "{{ $.Values.recording.importAllowAdmin }}"
{{- end }}
{{- if eq $name "voice-adapter-service" }}
- name: VOICE_ADAPTER_TRUSTED_SERVICE_SUBJECTS
value: "{{ $.Values.voiceAdapter.trustedServiceSubjects }}"
{{- end }}
{{- if eq $name "auth-service" }}
- name: OIDC_ENABLED
value: "{{ $.Values.auth.oidc.enabled }}"
- name: OIDC_PROVIDER
value: "{{ $.Values.auth.oidc.provider }}"
- name: OIDC_ISSUER_URL
value: "{{ $.Values.auth.oidc.issuerUrl }}"
- name: OIDC_CLIENT_ID
value: "{{ $.Values.auth.oidc.clientId }}"
- name: OIDC_CLIENT_SECRET
value: "{{ $.Values.auth.oidc.clientSecret }}"
- name: OIDC_REDIRECT_URI
value: "{{ $.Values.auth.oidc.redirectUri }}"
- name: OIDC_SCOPES
value: "{{ $.Values.auth.oidc.scopes }}"
- name: OIDC_ROLE_CLAIM
value: "{{ $.Values.auth.oidc.roleClaim }}"
- name: OIDC_ROLE_MAP_JSON
value: '{{ $.Values.auth.oidc.roleMapJson }}'
{{- end }}
{{- if $isGateway }}
- name: AUTH_SERVICE_URL
value: http://auth-service:8000
- name: AUDIT_SERVICE_URL
value: http://audit-service:8000
- name: CUSTOMER_SERVICE_URL
value: http://customer-service:8000
- name: INTERACTION_SERVICE_URL
value: http://interaction-service:8000
- name: ROUTING_SERVICE_URL
value: http://routing-service:8000
- name: VOICE_ADAPTER_SERVICE_URL
value: http://voice-adapter-service:8000
- name: RECORDING_SERVICE_URL
value: http://recording-service:8000
- name: IVR_SERVICE_URL
value: http://ivr-service:8000
- name: EVENT_BUS_SERVICE_URL
value: http://event-bus-service:8000
- name: ASTERISK_BRIDGE_SERVICE_URL
value: http://asterisk-bridge-service:8000
- name: TELEGRAM_ADAPTER_SERVICE_URL
value: http://telegram-adapter-service:8000
- name: AI_ORCHESTRATOR_SERVICE_URL
value: http://ai-orchestrator-service:8000
- name: AI_VOICE_RUNTIME_SERVICE_URL
value: http://ai-voice-runtime-service:8000
- name: WEBCHAT_ADAPTER_SERVICE_URL
value: http://webchat-adapter-service:8000
- name: EMAIL_ADAPTER_SERVICE_URL
value: http://email-adapter-service:8000
- name: KB_SERVICE_URL
value: http://kb-service:8000
- name: REPORTING_SERVICE_URL
value: http://reporting-service:8000
- name: SUPERVISOR_SERVICE_URL
value: http://supervisor-service:8000
{{- end }}
ports:
- containerPort: 8000
{{- if eq $name "ai-voice-runtime-service" }}
- containerPort: 9019
{{- end }}
{{- if eq $name "asterisk-bridge-service" }}
- containerPort: 4573
{{- end }}
resources:
requests:
cpu: {{ $svc.resources.requests.cpu }}
memory: {{ $svc.resources.requests.memory }}
limits:
cpu: {{ $svc.resources.limits.cpu }}
memory: {{ $svc.resources.limits.memory }}
startupProbe:
httpGet:
path: /health
port: 8000
failureThreshold: 30
periodSeconds: 5
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 20
periodSeconds: 15
timeoutSeconds: 2
{{- if $svc.persistence.enabled }}
volumeMounts:
- name: app-data
mountPath: /var/lib/mvp-cc/data
{{- end }}
{{- if $svc.persistence.enabled }}
volumes:
- name: app-data
persistentVolumeClaim:
claimName: {{ $name }}-data
{{- end }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ $name }}
namespace: {{ $.Values.namespace }}
spec:
selector:
app: {{ $name }}
ports:
- name: http
port: 8000
targetPort: 8000
{{- if eq $name "ai-voice-runtime-service" }}
- name: audiosocket
port: 9019
targetPort: 9019
{{- end }}
{{- if eq $name "asterisk-bridge-service" }}
- name: fastagi
port: 4573
targetPort: 4573
{{- end }}
type: {{ if $isGateway }}LoadBalancer{{ else }}ClusterIP{{ end }}
---
{{- if $svc.persistence.enabled }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ $name }}-data
namespace: {{ $.Values.namespace }}
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ $svc.persistence.size }}
---
{{- end }}
{{- if and $svc.podDisruptionBudget.enabled (gt (int $svc.replicas) 1) }}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ $name }}-pdb
namespace: {{ $.Values.namespace }}
spec:
minAvailable: {{ $svc.podDisruptionBudget.minAvailable }}
selector:
matchLabels:
app: {{ $name }}
---
{{- end }}
{{- if $svc.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ $name }}-hpa
namespace: {{ $.Values.namespace }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ $name }}
minReplicas: {{ $svc.autoscaling.minReplicas }}
maxReplicas: {{ $svc.autoscaling.maxReplicas }}
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: {{ $svc.autoscaling.targetCPUUtilizationPercentage }}
---
{{- end }}
{{- end }}