{{- if not .Values.agent }} {{- $nginxPort := int .Values.service.port | default 9090 -}} apiVersion: apps/v1 kind: Deployment metadata: name: {{ template "cost-analyzer.fullname" . }} labels: {{ include "cost-analyzer.commonLabels" . | nindent 4 }} {{- if .Values.kubecostDeployment }} {{- with .Values.kubecostDeployment.labels }} {{ toYaml . | indent 4 }} {{- end }} {{- end }} spec: {{- if .Values.kubecostDeployment }} replicas: {{ .Values.kubecostDeployment.replicas | default 1 }} {{- end }} selector: matchLabels: {{ include "cost-analyzer.selectorLabels" . | nindent 8}} {{- if .Values.kubecostDeployment }} {{- if .Values.kubecostDeployment.deploymentStrategy }} {{- with .Values.kubecostDeployment.deploymentStrategy }} strategy: {{ toYaml . | nindent 4 }} {{- end }} {{- else }} strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 1 type: RollingUpdate {{- end }} {{- end }} template: metadata: labels: {{ include "cost-analyzer.selectorLabels" . | nindent 8 }} {{- if .Values.global.additionalLabels }} {{ toYaml .Values.global.additionalLabels | nindent 8 }} {{- end }} {{- if .Values.kubecostDeployment }} {{- with .Values.kubecostDeployment.labels }} {{ toYaml . | indent 8 }} {{- end }} {{- end }} {{- if .Values.global.podAnnotations}} annotations: {{- with .Values.global.podAnnotations }} {{ toYaml . | indent 8 }} {{- end }} {{- end }} spec: {{- if .Values.kubecostFrontend.tls }} {{- if .Values.kubecostFrontend.tls.enabled }} securityContext: runAsUser: 0 {{- else }} securityContext: runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 {{- end }} {{- else if lt $nginxPort 1025 }} securityContext: runAsUser: 0 {{- else }} securityContext: runAsUser: 1001 runAsGroup: 1001 fsGroup: 1001 {{- end }} restartPolicy: Always serviceAccountName: {{ template "cost-analyzer.serviceAccountName" . }} volumes: {{- if .Values.hosted }} - name: config-store secret: defaultMode: 420 secretName: kubecost-thanos {{- end }} - name: tmp emptyDir: {} - name: nginx-conf configMap: name: nginx-conf items: - key: nginx.conf path: default.conf {{- if .Values.kubecostModel.etlBucketConfigSecret }} - name: etl-bucket-config secret: defaultMode: 420 secretName: {{ .Values.kubecostModel.etlBucketConfigSecret }} {{- end }} {{- if .Values.kubecostModel.federatedStorageConfigSecret }} - name: federated-storage-config secret: defaultMode: 420 secretName: {{ .Values.kubecostModel.federatedStorageConfigSecret }} {{- end }} {{- if .Values.kubecostProductConfigs }} {{- if .Values.kubecostProductConfigs.productKey }} {{- if .Values.kubecostProductConfigs.productKey.secretname }} - name: productkey-secret secret: secretName: {{ .Values.kubecostProductConfigs.productKey.secretname }} items: - key: productkey.json path: productkey.json {{- end }} {{- end -}} {{- if .Values.kubecostProductConfigs }} {{- if .Values.kubecostProductConfigs.gcpSecretName }} - name: gcp-key-secret secret: secretName: {{ .Values.kubecostProductConfigs.gcpSecretName }} items: - key: compute-viewer-kubecost-key.json path: service-key.json {{- end }} {{- end -}} {{- if .Values.kubecostProductConfigs.serviceKeySecretName }} - name: service-key-secret secret: secretName: {{ .Values.kubecostProductConfigs.serviceKeySecretName }} {{- else if .Values.kubecostProductConfigs.createServiceKeySecret }} - name: service-key-secret secret: secretName: cloud-service-key {{- end }} {{- if .Values.kubecostProductConfigs.azureStorageSecretName }} - name: azure-storage-config secret: secretName: {{ .Values.kubecostProductConfigs.azureStorageSecretName }} items: - key: azure-storage-config.json path: azure-storage-config.json {{- else if .Values.kubecostProductConfigs.azureStorageCreateSecret }} - name: azure-storage-config secret: secretName: azure-storage-config {{- end }} {{- if .Values.kubecostProductConfigs.cloudIntegrationSecret }} - name: cloud-integration secret: secretName: {{ .Values.kubecostProductConfigs.cloudIntegrationSecret }} items: - key: cloud-integration.json path: cloud-integration.json {{- end }} {{- if .Values.kubecostProductConfigs.clusters }} - name: kubecost-clusters configMap: name: kubecost-clusters {{- range .Values.kubecostProductConfigs.clusters }} {{- if .auth }} {{- if .auth.secretName }} - name: {{ .auth.secretName }} secret: secretName: {{ .auth.secretName }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{- if .Values.kubecostFrontend.tls }} {{- if .Values.kubecostFrontend.tls.enabled }} - name: tls secret: secretName : {{ .Values.kubecostFrontend.tls.secretName }} items: - key: tls.crt path: kc.crt - key: tls.key path: kc.key {{- end }} {{- end }} {{- if .Values.saml }} {{- if .Values.saml.enabled }} {{- if .Values.saml.secretName }} - name: secret-volume secret: secretName: {{ .Values.saml.secretName }} {{- end }} {{- if .Values.saml.metadataSecretName }} - name: metadata-secret-volume secret: secretName: {{ .Values.saml.metadataSecretName }} {{- end }} {{- if .Values.saml.rbac.enabled }} - name: saml-roles configMap: name: {{ template "cost-analyzer.fullname" . }}-saml {{- end }} {{- end }} {{- end }} {{- if .Values.oidc }} {{- if .Values.oidc.enabled }} - name: oidc-config configMap: name: {{ template "cost-analyzer.fullname" . }}-oidc {{- if .Values.oidc.secretName }} - name: oidc-client-secret secret: secretName: {{ .Values.oidc.secretName }} {{- end }} {{- end }} {{- end }} {{- if .Values.federatedETL.federator }} {{- if .Values.federatedETL.federator.enabled }} - name: federator-config configMap: name: {{ template "cost-analyzer.fullname" . }}-federator {{- end }} {{- end }} {{- if .Values.extraVolumes }} # Extra volume(s) {{- toYaml .Values.extraVolumes | nindent 8 }} {{- end }} - name: persistent-configs {{- if .Values.persistentVolume }} {{- if .Values.persistentVolume.enabled }} persistentVolumeClaim: {{- if .Values.persistentVolume.existingClaim }} claimName: {{ .Values.persistentVolume.existingClaim }} {{- else }} claimName: {{ template "cost-analyzer.fullname" . }} {{- end -}} {{- else }} emptyDir: {} {{- end -}} {{- else }} persistentVolumeClaim: claimName: {{ template "cost-analyzer.fullname" . }} {{- end }} {{- if and (.Values.kubecostModel.etlToDisk | default true) .Values.persistentVolume.dbPVEnabled }} - name: persistent-db {{- if .Values.persistentVolume }} {{- if .Values.persistentVolume.enabled }} persistentVolumeClaim: {{- if .Values.persistentVolume.dbExistingClaim }} claimName: {{ .Values.persistentVolume.dbExistingClaim }} {{- else }} claimName: {{ template "cost-analyzer.fullname" . }}-db {{- end -}} {{- else }} emptyDir: {} {{- end -}} {{- else }} persistentVolumeClaim: claimName: {{ template "cost-analyzer.fullname" . }}-db {{- end }} {{- end }} initContainers: {{- if .Values.supportNFS }} - name: config-db-perms-fix {{- if .Values.initChownDataImage }} image: {{ .Values.initChownDataImage }} {{- else }} image: busybox {{- end }} resources: {{ toYaml .Values.initChownData.resources | indent 12 }} {{- if and (.Values.kubecostModel.etlToDisk | default true) .Values.persistentVolume.dbPVEnabled }} command: ["sh", "-c", "/bin/chmod -R 777 /var/configs && /bin/chmod -R 777 /var/db"] {{- else }} command: ["sh", "-c", "/bin/chmod -R 777 /var/configs"] {{- end}} volumeMounts: - name: persistent-configs mountPath: /var/configs {{- if and (.Values.kubecostModel.etlToDisk | default true) .Values.persistentVolume.dbPVEnabled }} - name: persistent-db mountPath: /var/db {{- end }} securityContext: runAsUser: 0 {{ end }} containers: {{- if .Values.global.amp.enabled }} - name: sigv4proxy image: {{ .Values.sigV4Proxy.image }} {{- if .Values.sigV4Proxy.imagePullPolicy }} imagePullPolicy: {{ .Values.sigV4Proxy.imagePullPolicy }} {{- else }} imagePullPolicy: Always {{- end }} args: - --name - {{ .Values.sigV4Proxy.name }} - --region - {{ .Values.sigV4Proxy.region }} - --host - {{ .Values.sigV4Proxy.host }} {{- if .Values.sigV4Proxy.role_arn }} - --role-arn - {{ .Values.sigV4Proxy.role_arn }} {{- end }} - --port - :{{ .Values.sigV4Proxy.port }} ports: - name: aws-sigv4-proxy containerPort: {{ .Values.sigV4Proxy.port | int }} {{- if .Values.sigV4Proxy.extraEnv }} env: {{- toYaml .Values.sigV4Proxy.extraEnv | nindent 10 }} {{- end }} {{- end }} {{- if .Values.kubecostModel }} {{- if .Values.kubecostModel.openSourceOnly }} - image: quay.io/kubecost1/kubecost-cost-model:{{ .Values.imageVersion }} {{- else if .Values.kubecostModel.fullImageName }} - image: {{ .Values.kubecostModel.fullImageName }} {{- else if .Values.imageVersion }} - image: {{ .Values.kubecostModel.image }}:{{ .Values.imageVersion }} {{- else }} - image: {{ .Values.kubecostModel.image }}:prod-{{ $.Chart.AppVersion }} {{ end }} {{- else }} - image: gcr.io/kubecost1/cost-model:prod-{{ $.Chart.AppVersion }} {{ end }} name: cost-model {{- if .Values.kubecostModel.extraArgs }} args: {{- toYaml .Values.kubecostModel.extraArgs | nindent 12 }} {{- end }} {{- if .Values.kubecostModel.securityContext }} securityContext: {{- toYaml .Values.kubecostModel.securityContext | nindent 12 -}} {{ end }} {{- if .Values.kubecostModel.imagePullPolicy }} imagePullPolicy: {{ .Values.kubecostModel.imagePullPolicy }} {{- else }} imagePullPolicy: Always {{- end }} ports: - name: tcp-model containerPort: 9003 protocol: TCP - name: tcp-frontend containerPort: 9090 protocol: TCP resources: {{ toYaml .Values.kubecostModel.resources | indent 12 }} readinessProbe: httpGet: path: /healthz port: 9003 initialDelaySeconds: 30 periodSeconds: 10 failureThreshold: 200 volumeMounts: {{- if .Values.hosted }} - name: config-store mountPath: /var/secrets readOnly: true {{- end }} - name: persistent-configs mountPath: /var/configs {{- if .Values.extraVolumeMounts }} # Extra volume mount(s) {{- toYaml .Values.extraVolumeMounts | nindent 12 }} {{- end }} {{- if .Values.kubecostModel.etlBucketConfigSecret }} - name: etl-bucket-config mountPath: /var/configs/etl readOnly: true {{- else if and (.Values.kubecostModel.etlToDisk | default true) .Values.persistentVolume.dbPVEnabled }} - name: persistent-db mountPath: /var/db {{- end }} {{- if .Values.kubecostModel.federatedStorageConfigSecret }} - name: federated-storage-config mountPath: /var/configs/etl/federated readOnly: true {{- end }} {{- if .Values.federatedETL }} {{- if .Values.federatedETL.federator.enabled }} - name: federator-config mountPath: /var/configs/federator {{- end }} {{- end }} {{- if .Values.kubecostProductConfigs }} {{- if .Values.kubecostProductConfigs.productKey }} {{- if .Values.kubecostProductConfigs.productKey.secretname }} - name: productkey-secret mountPath: /var/configs/productkey {{- end }} {{- end }} {{- if .Values.kubecostProductConfigs.gcpSecretName }} - name: gcp-key-secret mountPath: /var/secrets {{- end }} {{- if or .Values.kubecostProductConfigs.azureStorageSecretName .Values.kubecostProductConfigs.azureStorageCreateSecret }} - name: azure-storage-config mountPath: /var/azure-storage-config {{- end }} {{- if .Values.kubecostProductConfigs.cloudIntegrationSecret }} - name: cloud-integration mountPath: /var/cloud-integration {{- end }} {{- if or .Values.kubecostProductConfigs.serviceKeySecretName .Values.kubecostProductConfigs.createServiceKeySecret }} - name: service-key-secret mountPath: /var/secrets {{- end }} {{- if .Values.kubecostProductConfigs.clusters }} - name: kubecost-clusters mountPath: /var/configs/clusters {{- range .Values.kubecostProductConfigs.clusters }} {{- if .auth }} {{- if .auth.secretName }} - name: {{ .auth.secretName }} mountPath: /var/secrets/{{ .auth.secretName }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{- if .Values.saml }} {{- if .Values.saml.enabled }} {{- if .Values.saml.secretName }} - name: secret-volume mountPath: /var/configs/secret-volume {{- end }} {{- if .Values.saml.metadataSecretName }} - name: metadata-secret-volume mountPath: /var/configs/metadata-secret-volume {{- end }} {{- if .Values.saml.rbac.enabled }} - name: saml-roles mountPath: /var/configs/saml {{- end }} {{- end }} {{- end }} {{- if .Values.oidc }} {{- if .Values.oidc.enabled }} - name: oidc-config mountPath: /var/configs/oidc {{- if .Values.oidc.secretName }} - name: oidc-client-secret mountPath: /var/configs/oidc-client-secret {{- end }} {{- end }} {{- end }} env: {{- if .Values.global.grafana }} - name: GRAFANA_ENABLED value: {{ (quote .Values.global.grafana.enabled) | default (quote false) }} {{- end}} {{- if .Values.kubecostModel.extraEnv -}} {{ toYaml .Values.kubecostModel.extraEnv | nindent 12 }} {{- end }} {{- if .Values.reporting }} {{- if .Values.reporting.valuesReporting }} - name: HELM_VALUES value: {{ template "cost-analyzer.filterEnabled" .Values }} {{- end }} {{- end }} {{- if .Values.alertConfigmapName }} - name: ALERT_CONFIGMAP_NAME value: {{ .Values.alertConfigmapName }} {{- end }} {{- if .Values.productConfigmapName }} - name: PRODUCT_CONFIGMAP_NAME value: {{ .Values.productConfigmapName }} {{- end }} {{- if .Values.appConfigmapName }} - name: APP_CONFIGMAP_NAME value: {{ .Values.appConfigmapName }} {{- end }} {{- if .Values.kubecostModel.softMemoryLimit }} - name: GOMEMLIMIT value: {{ .Values.kubecostModel.softMemoryLimit }} {{- end }} {{- if .Values.assetReportConfigmapName }} - name: ASSET_REPORT_CONFIGMAP_NAME value: {{ .Values.assetReportConfigmapName }} {{- end }} {{- if .Values.savedReportConfigmapName }} - name: SAVED_REPORT_CONFIGMAP_NAME value: {{ .Values.savedReportConfigmapName }} {{- end }} {{- if .Values.groupFiltersConfigmapName }} - name: GROUP_FILTERS_CONFIGMAP_NAME value: {{ .Values.groupFiltersConfigmapName }} {{- end }} {{- if .Values.pricingConfigmapName }} - name: PRICING_CONFIGMAP_NAME value: {{ .Values.pricingConfigmapName }} {{- end }} {{- if .Values.metricsConfigmapName }} - name: METRICS_CONFIGMAP_NAME value: {{ .Values.metricsConfigmapName }} {{- end }} - name: READ_ONLY value: {{ (quote .Values.readonly) | default (quote false) }} - name: PROMETHEUS_SERVER_ENDPOINT valueFrom: configMapKeyRef: name: {{ template "cost-analyzer.fullname" . }} key: prometheus-server-endpoint - name: CLOUD_PROVIDER_API_KEY value: "AIzaSyDXQPG_MHUEy9neR7stolq6l0ujXmjJlvk" # The GCP Pricing API requires a key. {{- if .Values.kubecostProductConfigs }} {{- if .Values.kubecostProductConfigs.gcpSecretName }} - name: GOOGLE_APPLICATION_CREDENTIALS value: /var/configs/key.json {{- end }} {{- end }} - name: CONFIG_PATH value: /var/configs/ - name: DB_PATH value: /var/db/ - name: CLUSTER_PROFILE {{- if .Values.kubecostProductConfigs }} value: {{ .Values.kubecostProductConfigs.clusterProfile | default "production" }} {{- else }} value: production {{- end }} {{- if .Values.kubecostProductConfigs }} {{- if .Values.kubecostProductConfigs.productKey }} {{- if .Values.kubecostProductConfigs.productKey.mountPath }} - name: PRODUCT_KEY_MOUNT_PATH value: {{ .Values.kubecostProductConfigs.productKey.mountPath }} {{- end }} {{- end }} {{- if .Values.kubecostProductConfigs.ingestPodUID }} - name: INGEST_POD_UID value: {{ (quote .Values.kubecostProductConfigs.ingestPodUID) }} {{- end }} {{- end }} - name: REMOTE_WRITE_PASSWORD value: {{ .Values.remoteWrite.postgres.auth.password }} {{- if .Values.remoteWrite.postgres.enabled }} - name: REMOTE_WRITE_ENABLED value: "true" {{- end }} {{- if .Values.global.thanos.queryServiceBasicAuthSecretName}} - name: MC_BASIC_AUTH_USERNAME valueFrom: secretKeyRef: name: {{ .Values.global.thanos.queryServiceBasicAuthSecretName }} key: USERNAME - name: MC_BASIC_AUTH_PW valueFrom: secretKeyRef: name: {{ .Values.global.thanos.queryServiceBasicAuthSecretName }} key: PASSWORD {{- end }} {{- if .Values.global.prometheus.queryServiceBasicAuthSecretName}} - name: DB_BASIC_AUTH_USERNAME valueFrom: secretKeyRef: name: {{ .Values.global.prometheus.queryServiceBasicAuthSecretName }} key: USERNAME - name: DB_BASIC_AUTH_PW valueFrom: secretKeyRef: name: {{ .Values.global.prometheus.queryServiceBasicAuthSecretName }} key: PASSWORD {{- end }} {{- if .Values.global.prometheus.queryServiceBearerTokenSecretName }} - name: DB_BEARER_TOKEN valueFrom: secretKeyRef: name: {{ .Values.global.prometheus.queryServiceBearerTokenSecretName }} key: TOKEN {{- end }} {{- if .Values.global.thanos.queryServiceBearerTokenSecretName }} - name: MC_BEARER_TOKEN valueFrom: secretKeyRef: name: {{ .Values.global.thanos.queryServiceBearerTokenSecretName }} key: TOKEN {{- end }} {{- if .Values.global.prometheus.insecureSkipVerify }} - name: INSECURE_SKIP_VERIFY value: {{ (quote .Values.global.prometheus.insecureSkipVerify) }} {{- end }} {{- if .Values.pricingCsv }} {{- if .Values.pricingCsv.enabled }} - name: USE_CSV_PROVIDER value: "true" - name: CSV_PATH value: {{ .Values.pricingCsv.location.URI }} - name: CSV_REGION value: {{ .Values.pricingCsv.location.region }} {{- if eq .Values.pricingCsv.location.provider "AWS"}} {{- if .Values.pricingCsv.location.csvAccessCredentials }} - name: AWS_ACCESS_KEY_ID valueFrom: secretKeyRef: name: {{ .Values.pricingCsv.location.csvAccessCredentials }} key: AWS_ACCESS_KEY_ID - name: AWS_SECRET_ACCESS_KEY valueFrom: secretKeyRef: name: {{ .Values.pricingCsv.location.csvAccessCredentials }} key: AWS_SECRET_ACCESS_KEY {{- end }} {{- end }} {{- end }} {{- end }} {{- if .Values.kubecostMetrics }} - name: EMIT_POD_ANNOTATIONS_METRIC value: {{ (quote .Values.kubecostMetrics.emitPodAnnotations) | default (quote false) }} - name: EMIT_NAMESPACE_ANNOTATIONS_METRIC value: {{ (quote .Values.kubecostMetrics.emitNamespaceAnnotations) | default (quote false) }} {{- end }} {{- if .Values.kubecostMetrics }} - name: EMIT_KSM_V1_METRICS value: {{ (quote .Values.kubecostMetrics.emitKsmV1Metrics) | default (quote true) }} {{- end }} {{- if .Values.kubecostMetrics }} - name: EMIT_KSM_V1_METRICS_ONLY # ONLY emit KSM v1 metrics that do not exist in KSM 2 by default value: {{ (quote .Values.kubecostMetrics.emitKsmV1MetricsOnly) | default (quote false) }} {{- end }} {{- if .Values.reporting }} - name: LOG_COLLECTION_ENABLED value: {{ (quote .Values.reporting.logCollection) | default (quote true) }} - name: PRODUCT_ANALYTICS_ENABLED value: {{ (quote .Values.reporting.productAnalytics) | default (quote true) }} - name: ERROR_REPORTING_ENABLED value: {{ (quote .Values.reporting.errorReporting ) | default (quote true) }} - name: VALUES_REPORTING_ENABLED value: {{ (quote .Values.reporting.valuesReporting) | default (quote true) }} {{- if .Values.reporting.errorReporting }} - name: SENTRY_DSN value: "https://71964476292e4087af8d5072afe43abd@o394722.ingest.sentry.io/5245431" {{- end }} {{- end }} - name: LEGACY_EXTERNAL_API_DISABLED value: {{ (quote .Values.kubecostModel.legacyOutOfClusterAPIDisabled) | default (quote false) }} - name: OUT_OF_CLUSTER_PROM_METRICS_ENABLED value: {{ (quote .Values.kubecostModel.outOfClusterPromMetricsEnabled) | default (quote false) }} - name: CACHE_WARMING_ENABLED value: {{ (quote .Values.kubecostModel.warmCache) | default (quote true) }} - name: SAVINGS_CACHE_WARMING_ENABLED value: {{ (quote .Values.kubecostModel.warmSavingsCache) | default (quote true) }} - name: ETL_ENABLED value: {{ (quote .Values.kubecostModel.etl) | default (quote true) }} {{- if .Values.kubecostModel.etlReadOnlyMode }} - name: ETL_READ_ONLY value: "true" {{- end }} {{- if .Values.kubecostModel.etlBucketConfigSecret }} - name: ETL_TO_DISK_ENABLED value: "false" - name: ETL_BUCKET_CONFIG value: "/var/configs/etl/object-store.yaml" {{- else }} - name: ETL_TO_DISK_ENABLED value: {{ (quote .Values.kubecostModel.etlToDisk) | default (quote true) }} {{- end }} {{- if .Values.kubecostModel.federatedStorageConfigSecret }} - name: FEDERATED_STORE_CONFIG value: "/var/configs/etl/federated/federated-store.yaml" {{- end }} {{- if or .Values.federatedETL.federatedCluster .Values.kubecostModel.federatedStorageConfigSecret }} - name: FEDERATED_CLUSTER value: "true" {{- end}} {{- if .Values.federatedETL.primaryCluster }} - name: FEDERATED_PRIMARY_CLUSTER value: "true" {{- end}} {{- if .Values.federatedETL.redirectS3Backup }} - name: FEDERATED_REDIRECT_BACKUP value: "true" {{- end}} {{- if .Values.federatedETL.useExistingS3Config }} - name: FEDERATED_USE_EXISTING_CONFIG value: "true" {{- end}} {{- if .Values.federatedETL.federator.enabled }} - name: FEDERATED_FEDERATOR_ENABLED value: "true" {{- end}} - name: ETL_STORE_READ_ONLY value: {{ (quote .Values.kubecostModel.etlStoreReadOnly) | default (quote false) }} - name : ETL_CLOUD_USAGE_ENABLED {{- if kindIs "bool" .Values.kubecostModel.etlCloudUsage }} value: {{ (quote .Values.kubecostModel.etlCloudUsage) }} {{- else if kindIs "bool" .Values.kubecostModel.etlCloudAsset }} value: {{ (quote .Values.kubecostModel.etlCloudAsset) }} {{- else }} value: "true" {{- end }} - name: CLOUD_ASSETS_EXCLUDE_PROVIDER_ID value: {{ (quote .Values.kubecostModel.cloudAssetsExcludeProviderID) | default (quote false) }} - name: ETL_CLOUD_REFRESH_RATE_HOURS value: {{ (quote .Values.kubecostModel.etlCloudRefreshRateHours) | default (quote 6) }} - name: ETL_CLOUD_QUERY_WINDOW_DAYS value: {{ (quote .Values.kubecostModel.etlCloudQueryWindowDays) | default (quote 7) }} - name: ETL_CLOUD_RUN_WINDOW_DAYS value: {{ (quote .Values.kubecostModel.etlCloudRunWindowDays) | default (quote 3) }} {{- if .Values.persistentVolume.dbPVEnabled }} - name: ETL_PATH_PREFIX value: "/var/db" {{- end }} - name: ETL_RESOLUTION_SECONDS value: {{ (quote .Values.kubecostModel.etlResolutionSeconds) | default (quote 300) }} - name: ETL_MAX_PROMETHEUS_QUERY_DURATION_MINUTES value: {{ (quote .Values.kubecostModel.maxPrometheusQueryDurationMinutes) | default (quote 1440) }} - name: ETL_DAILY_STORE_DURATION_DAYS value: {{ (quote .Values.kubecostModel.etlDailyStoreDurationDays) | default (quote 91) }} - name: ETL_HOURLY_STORE_DURATION_HOURS value: {{ (quote .Values.kubecostModel.etlHourlyStoreDurationHours) | default (quote 49) }} - name: ETL_FILE_STORE_ENABLED value: {{ (quote .Values.kubecostModel.etlFileStoreEnabled) | default (quote true) }} - name: ETL_ASSET_RECONCILIATION_ENABLED value: {{ (quote .Values.kubecostModel.etlAssetReconciliationEnabled) | default (quote true) }} - name: ETL_USE_UNBLENDED_COST value: {{ (quote .Values.kubecostModel.etlUseUnblendedClost) | default (quote false) }} {{- with .Values.kubecostModel.cloudCost }} - name: CLOUD_COST_ENABLED value: {{ (quote .enabled) | default (quote false) }} {{- with .labelList }} - name: CLOUD_COST_IS_INCLUDE_LIST value: {{ (quote .IsIncludeList) | default (quote false) }} - name: CLOUD_COST_LABEL_LIST value: {{ (quote .labels) }} {{- end }} - name: CLOUD_COST_TOP_N value: {{ (quote .topNItems) | default (quote 1000) }} {{- end }} - name: CONTAINER_STATS_ENABLED value: {{ (quote .Values.kubecostModel.containerStatsEnabled) | default (quote false) }} - name: RECONCILE_NETWORK value: {{ (quote .Values.kubecostModel.reconcileNetwork) | default (quote true) }} {{- if .Values.systemProxy.enabled }} - name: HTTP_PROXY value: {{ .Values.systemProxy.httpProxyUrl }} - name: http_proxy value: {{ .Values.systemProxy.httpProxyUrl }} - name: HTTPS_PROXY value: {{ .Values.systemProxy.httpsProxyUrl }} - name: https_proxy value: {{ .Values.systemProxy.httpsProxyUrl }} - name: NO_PROXY value: {{ .Values.systemProxy.noProxy }} - name: no_proxy value: {{ .Values.systemProxy.noProxy }} {{- end }} {{- if .Values.kubecostMetrics }} {{- if .Values.kubecostMetrics.exporter }} - name: KUBECOST_METRICS_POD_ENABLED value: {{ (quote .Values.kubecostMetrics.exporter.enabled) | default (quote false) }} {{- end }} {{- end }} - name: PV_ENABLED value: {{ (quote .Values.persistentVolume.enabled) | default (quote true) }} - name: MAX_QUERY_CONCURRENCY value: {{ (quote .Values.kubecostModel.maxQueryConcurrency) | default (quote 5) }} - name: UTC_OFFSET value: {{ (quote .Values.kubecostModel.utcOffset) | default (quote ) }} {{- if .Values.networkCosts }} {{- if .Values.networkCosts.enabled }} - name: NETWORK_COSTS_PORT value: {{ quote .Values.networkCosts.port | default (quote 3001) }} {{- end }} {{- end }} {{- /* If queryService is set, the cost-analyzer will always pass THANOS_ENABLED as true to ensure that the custom query service target is used. The global.thanos.enabled flag does not have any affect on this behavior. */}} {{- if .Values.global.thanos.queryService }} - name: THANOS_ENABLED value: "true" - name: THANOS_QUERY_URL value: {{ .Values.global.thanos.queryService }} - name: THANOS_QUERY_OFFSET value: {{ .Values.global.thanos.queryOffset | default "3h" }} - name: THANOS_MAX_SOURCE_RESOLUTION value: {{ .Values.kubecostModel.maxSourceResolution | default "raw" }} {{- else if and .Values.global.thanos.enabled .Values.thanos }} {{- if .Values.thanos.query }} {{- if .Values.thanos.query.enabled }} - name: THANOS_ENABLED {{- if .Values.hosted }} value: "false" {{- else }} value: "true" {{- end }} - name: THANOS_QUERY_URL value: http://{{ .Release.Name }}-thanos-query-frontend-http.{{ .Release.Namespace }}:{{ .Values.thanos.queryFrontend.http.port }} - name: THANOS_QUERY_OFFSET value: {{ .Values.global.thanos.queryOffset | default "3h" }} - name: THANOS_MAX_SOURCE_RESOLUTION value: {{ .Values.kubecostModel.maxSourceResolution | default "raw" }} {{- end }} {{- end }} {{- end }} {{- if .Values.oidc.enabled }} - name: OIDC_ENABLED value: "true" {{- end}} {{- if .Values.saml }} {{- if .Values.saml.enabled }} - name: SAML_ENABLED value: "true" - name: IDP_URL value: {{ .Values.saml.idpMetadataURL }} - name: SP_HOST value: {{ .Values.saml.appRootURL }} {{- if .Values.saml.audienceURI }} - name: AUDIENCE_URI value: {{ .Values.saml.audienceURI }} {{- end }} {{- if .Values.saml.isGLUUProvider }} - name: GLUU_SAML_PROVIDER value: {{ (quote .Values.saml.isGLUUProvider) }} {{- end }} {{- if .Values.saml.nameIDFormat }} - name: NAME_ID_FORMAT value: {{ .Values.saml.nameIDFormat }} {{- end}} {{- if .Values.saml.authTimeout }} - name: AUTH_TOKEN_TIMEOUT value: {{ (quote .Values.saml.authTimeout) }} {{- end}} {{- if .Values.saml.redirectURL }} - name: LOGOUT_REDIRECT_URL value: {{ .Values.saml.redirectURL }} {{- end}} {{- if .Values.saml.rbac.enabled }} - name: SAML_RBAC_ENABLED value: "true" {{- end }} {{- end }} {{- end }} {{- if and (.Values.prometheus.server.global.external_labels.cluster_id) (not .Values.prometheus.server.clusterIDConfigmap) }} - name: CLUSTER_ID value: {{ .Values.prometheus.server.global.external_labels.cluster_id }} {{- end }} {{- if .Values.prometheus.server.clusterIDConfigmap }} - name: CLUSTER_ID valueFrom: configMapKeyRef: name: {{ .Values.prometheus.server.clusterIDConfigmap }} key: CLUSTER_ID {{- end }} {{- if .Values.remoteWrite.postgres.installLocal }} - name: SQL_ADDRESS value: pgprometheus {{- else }} - name: SQL_ADDRESS value: {{ .Values.remoteWrite.postgres.remotePostgresAddress }} {{- end }} {{- if .Values.kubecostModel.promClusterIDLabel }} - name: PROM_CLUSTER_ID_LABEL value: {{ .Values.kubecostModel.promClusterIDLabel }} {{- end }} {{- if .Values.hosted }} - name: KUBECOST_CONFIG_BUCKET value: /var/secrets/object-store.yaml - name: CLUSTER_INFO_FILE_ENABLED value: "true" - name: CLUSTER_CACHE_FILE_ENABLED value: "true" {{- end }} {{- if .Values.reporting.googleAnalyticsTag }} - name: GOOGLE_ANALYTICS_TAG value: {{ .Values.reporting.googleAnalyticsTag }} {{- end }} {{- /* Leader/Follower has baseline requirements before enabling: * ETL FileStore Enabled * Bucket Backup Configured * Replicas > 1 */}} {{- if .Values.kubecostDeployment }} {{- if .Values.kubecostDeployment.leaderFollower }} {{- if .Values.kubecostDeployment.leaderFollower.enabled -}} {{- $etlFileStore := .Values.kubecostModel.etlFileStoreEnabled }} {{- if not $etlFileStore }} {{- fail "Leader/Follower requires kubecostModel.etlFileStoreEnabled be true." }} {{- end -}} {{- if (eq (quote .Values.kubecostModel.etlBucketConfigSecret) "") }} {{- fail "Leader/Follower requires kubecostModel.etlBucketConfigSecret be valid." }} {{- end -}} {{- $replicas := .Values.kubecostDeployment.replicas | default 1 }} {{- if not (gt (int $replicas) 1) }} {{- fail "Leader/Follower should be used with kubecostDeployment.replicas > 1" }} {{- end }} {{- /* Checks to ensure that the named template returns true if we've made it here */}} {{- $result := include "cost-analyzer.leaderFollowerEnabled" . }} {{- if not $result }} {{- fail (quote $result) }} {{- end }} - name: LEADER_FOLLOWER_ENABLED value: "true" {{- end }} {{- end }} {{- end }} - name: RELEASE_NAME value: {{ .Release.Name }} - name: KUBECOST_NAMESPACE value: {{ .Release.Namespace }} - name: POD_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name - name: KUBECOST_TOKEN valueFrom: configMapKeyRef: name: {{ template "cost-analyzer.fullname" . }} key: kubecost-token {{- if .Values.kubecostFrontend }} {{- if .Values.kubecostFrontend.fullImageName }} - image: {{ .Values.kubecostFrontend.fullImageName }} {{- else if .Values.imageVersion }} - image: {{ .Values.kubecostFrontend.image }}:{{ .Values.imageVersion }} {{- else }} - image: {{ .Values.kubecostFrontend.image }}:prod-{{ $.Chart.AppVersion }} {{ end }} {{- else }} - image: gcr.io/kubecost1/frontend:prod-{{ $.Chart.AppVersion }} {{ end }} {{- if .Values.kubecostFrontend.tls }} {{- if .Values.kubecostFrontend.tls.enabled }} command: ["nginx", "-g", "daemon off;"] ports: - containerPort: 443 {{- end }} {{- end }} env: - name: GET_HOSTS_FROM value: dns {{- if .Values.kubecostFrontend.extraEnv -}} {{ toYaml .Values.kubecostFrontend.extraEnv | nindent 12 }} {{- end }} name: cost-analyzer-frontend {{- if .Values.kubecostFrontend.securityContext }} securityContext: {{- toYaml .Values.kubecostFrontend.securityContext | nindent 12 }} {{ end }} volumeMounts: - name: tmp mountPath: /tmp - name: nginx-conf mountPath: /etc/nginx/conf.d/ {{- if .Values.kubecostFrontend.tls }} {{- if .Values.kubecostFrontend.tls.enabled }} - name: tls mountPath: /etc/ssl/certs {{- end }} {{- end }} resources: {{ toYaml .Values.kubecostFrontend.resources | indent 12 }} {{- if .Values.kubecostFrontend.imagePullPolicy }} imagePullPolicy: {{ .Values.kubecostFrontend.imagePullPolicy }} {{- else }} imagePullPolicy: Always {{- end }} readinessProbe: httpGet: path: /healthz port: 9003 initialDelaySeconds: 30 periodSeconds: 10 failureThreshold: 200 {{- if .Values.imagePullSecrets }} imagePullSecrets: {{ toYaml .Values.imagePullSecrets | indent 2 }} {{- end }} {{- if .Values.priority }} {{- if .Values.priority.enabled }} {{- if gt (len .Values.priority.name) 0 }} priorityClassName: {{ .Values.priority.name }} {{- else }} priorityClassName: {{ template "cost-analyzer.fullname" . }}-priority {{- end }} {{- end }} {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.affinity }} affinity: {{- toYaml . | nindent 8 }} {{- end }} {{- end }}