diff --git a/charts/tilegen-api/.gitattributes b/charts/tilegen-api/.gitattributes
new file mode 100644
index 00000000..3fbaa038
--- /dev/null
+++ b/charts/tilegen-api/.gitattributes
@@ -0,0 +1,3 @@
+* text=auto
+*.yaml text eol=lf
+*.tpl text eol=lf
diff --git a/charts/tilegen-api/.helmignore b/charts/tilegen-api/.helmignore
new file mode 100644
index 00000000..50af0317
--- /dev/null
+++ b/charts/tilegen-api/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/charts/tilegen-api/Chart.yaml b/charts/tilegen-api/Chart.yaml
new file mode 100644
index 00000000..47d00fb7
--- /dev/null
+++ b/charts/tilegen-api/Chart.yaml
@@ -0,0 +1,13 @@
+apiVersion: v2
+name: tilegen
+description: API for generating vector tiles from user data
+
+type: application
+
+version: 0.0.1
+appVersion: 0.0.1
+
+maintainers:
+- name: 2gis
+ url: https://github.com/2gis
+ email: on-premise@2gis.com
diff --git a/charts/tilegen-api/README.md b/charts/tilegen-api/README.md
new file mode 100644
index 00000000..f072e996
--- /dev/null
+++ b/charts/tilegen-api/README.md
@@ -0,0 +1,113 @@
+# 2GIS TILEGEN API Service
+
+## Values
+
+### Docker Registry settings
+
+| Name | Description | Value |
+| --------------------- | --------------------------------------------------------------------------------------- | ----- |
+| `dgctlDockerRegistry` | Docker Registry endpoint where On-Premise services' images reside. Format: `host:port`. | `""` |
+
+### **Common settings**
+
+| Name | Description | Value |
+| ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- |
+| `appName` | Name of the service. | `tilegen-api` |
+| `replicaCount` | A replica count for the pod. | `1` |
+| `imagePullSecrets` | Kubernetes image pull secrets. | `[]` |
+| `nameOverride` | Base name to use in all the Kubernetes entities deployed by this chart. | `""` |
+| `fullnameOverride` | Base fullname to use in all the Kubernetes entities deployed by this chart. | `""` |
+| `nodeSelector` | Kubernetes [node selectors](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector). | `{}` |
+| `affinity` | Kubernetes pod [affinity settings](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity). | `{}` |
+| `priorityClassName` | Kubernetes [pod priority](https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/). | `""` |
+| `terminationGracePeriodSeconds` | Kubernetes [termination grace period](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/). | `60` |
+| `tolerations` | Kubernetes [tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) settings. | `[]` |
+| `podAnnotations` | Kubernetes [pod annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/). | `{}` |
+| `podLabels` | Kubernetes [pod labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/). | `{}` |
+| `annotations` | Kubernetes [annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/). | `{}` |
+| `labels` | Kubernetes [labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/). | `{}` |
+| `revisionHistoryLimit` | Revision history limit (used for [rolling back](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) a deployment). | `3` |
+| `Strategy` | settings | |
+| `strategy.type` | Type of Kubernetes deployment. Can be `Recreate` or `RollingUpdate`. | `RollingUpdate` |
+| `strategy.rollingUpdate.maxUnavailable` | Maximum number of pods that can be created over the desired number of pods when doing [rolling update](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-update-deployment). | `0` |
+| `strategy.rollingUpdate.maxSurge` | Maximum number of pods that can be unavailable during the [rolling update](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-update-deployment) process. | `1` |
+| `Service` | settings | |
+| `service.annotations` | Kubernetes [service annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) | `{}` |
+| `service.labels` | Kubernetes [service labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/). | `{}` |
+| `service.type` | Kubernetes [service type](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types). | `ClusterIP` |
+| `service.port` | PRO API service port. | `80` |
+| `Kubernetes` | (https://github.com/kubernetes/autoscaler/blob/master/vertical-pod-autoscaler/README.md) settings | |
+| `vpa.enabled` | If VPA is enabled for the service. | `false` |
+| `vpa.updateMode` | VPA [update mode](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler#quick-start). | `Auto` |
+| `vpa.minAllowed.cpu` | Lower limit for the number of CPUs to which the autoscaler can scale down. | `100m` |
+| `vpa.minAllowed.memory` | Lower limit for the RAM size to which the autoscaler can scale down. | `256M` |
+| `vpa.maxAllowed.cpu` | Upper limit for the number of CPUs to which the autoscaler can scale up. | `1` |
+| `vpa.maxAllowed.memory` | Upper limit for the RAM size to which the autoscaler can scale up. | `1024M` |
+| `Deployment` | settings | |
+| `image.repository` | Repository | `2gis-on-premise/tilegen-api` |
+| `image.tag` | Tag | `1.1.6` |
+| `image.pullPolicy` | Pull Policy | `IfNotPresent` |
+| `TileGen` | Storage configuration | |
+| `s3.host` | S3 endpoint. Format: `host:port`. **Required** | `""` |
+| `s3.accessKey` | S3 access key for accessing the bucket. **Required** | `""` |
+| `s3.secretKey` | S3 secret key for accessing the bucket. **Required** | `""` |
+| `s3.vectorTilesBucket` | S3 bucket for storing vector tiles data. **Required** | `""` |
+| `TileGen` | Api configuration | |
+| `api.serviceAccount` | Kubernetes service account | `runner` |
+| `api.tempPath` | Path to directory used for temp data | `/tmp` |
+| `api.allowAnyOrigin` | Cors policy: allow any origin to perform requests to pro-api service | `false` |
+| `api.logging` | Logging settings | |
+| `api.logging.format` | Log message format, possible options: 'default' - compact json, 'renderedCompactJson' - rendered json format, 'simple' - plain text | `simple` |
+| `api.logging.targets` | Collection of logging targets divided by comma. Currently only 'console' and 'database' are supported. Console is used by default (no need to specify). | `""` |
+| `Redis` | settings (supported version 6.x) | |
+| `redis.host` | Redis host address. **Required** | `""` |
+| `redis.port` | Redis port. **Required** | `6379` |
+| `redis.username` | Username used to connect to Redis | `""` |
+| `redis.password` | Password used to connect to Redis | `""` |
+| `Tile` | server importer settings | |
+| `tilesImporter.secure` | Uses https protocol | `false` |
+| `tilesImporter.hosts` | Comma separated tile server importer hosts. Example: `tiles1.importer.host,tiles2.importer.host` **Required** | `""` |
+| `TileGen` | processor job settings | |
+| `taskProcessor.repository` | Docker Repository Image. | `2gis-on-premise/tilegen-processor` |
+| `taskProcessor.tag` | Docker image tag. | `1.1.6` |
+| `taskProcessor.backoffLimit` | The number of [retries](https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-backoff-failure-policy) before considering a Job as failed. | `1` |
+| `taskProcessor.successfulJobsHistoryLimit` | How many completed and failed jobs should be kept. See [docs](https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/#jobs-history-limits). | `5` |
+| `taskProcessor.nodeSelector` | Kubernetes [node selectors](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector). | `{}` |
+| `taskProcessor.tempVolume` | Temporary data storage volume | `{}` |
+| `taskProcessor.resources` | **Limits for the tile processor job** | |
+| `taskProcessor.resources.requests.cpu` | A CPU request. | `1` |
+| `taskProcessor.resources.requests.memory` | A memory request. | `1Gi` |
+| `taskProcessor.resources.limits.cpu` | A CPU limit. | `4` |
+| `taskProcessor.resources.limits.memory` | A memory limit. | `24Gi` |
+| `taskProcessor.maxParallelJobs` | How many import jobs can be run simultaneously | `1` |
+| `Limits` | | |
+| `resources` | **Limits for the application service** | |
+| `resources.requests.cpu` | A CPU request. | `400m` |
+| `resources.requests.memory` | A memory request. | `256M` |
+| `resources.limits.cpu` | A CPU limit. | `1` |
+| `resources.limits.memory` | A memory limit. | `1024M` |
+| `Kubernetes` | (https://kubernetes.io/docs/concepts/services-networking/ingress/) settings | |
+| `ingress.enabled` | If Ingress is enabled for the service. | `false` |
+| `ingress.className` | Name of the Ingress controller class. | `nginx` |
+| `ingress.hosts[0].host` | Hostname for the Ingress service. | `tilegen-api.host` |
+| `ingress.hosts[0].paths[0].path` | Path of the host for the Ingress service. | `/` |
+| `ingress.hosts[0].paths[0].pathType` | Type of the path for the Ingress service. | `Prefix` |
+| `ingress.tls` | TLS configuration. | `[]` |
+
+
+## Installing
+
+1. Create a configuration file values-api.yaml and fill in all the required parameters according to the docs above.
+2. Then execute command:
+`- helm upgrade "tilegen-api" --install --atomic --wait --wait-for-jobs --timeout 10m --values ./values-api.yaml`
+3. Check installation by executing request
+`https://tilegen-api.host/health/ready`
+4. Check installation by executing request
+`https://tilegen-api-staging.web-staging.2gis.ru/tasks/1`
+
The response must contain error message "Task not found", response http code = 404
+
+## Maintainers
+
+| Name | Email | Url |
+| ---- | ------ | --- |
+| 2gis | | |
diff --git a/charts/tilegen-api/templates/tilegen/NOTES.txt b/charts/tilegen-api/templates/tilegen/NOTES.txt
new file mode 100644
index 00000000..66570a0a
--- /dev/null
+++ b/charts/tilegen-api/templates/tilegen/NOTES.txt
@@ -0,0 +1,2 @@
+Release - {{ .Release.Name }}
+Namespace - {{ .Release.Namespace }}
diff --git a/charts/tilegen-api/templates/tilegen/_helpers.tpl b/charts/tilegen-api/templates/tilegen/_helpers.tpl
new file mode 100644
index 00000000..4a3382c3
--- /dev/null
+++ b/charts/tilegen-api/templates/tilegen/_helpers.tpl
@@ -0,0 +1,48 @@
+{{- define "api.name" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Values.appName .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 "task-processor-job.name" -}}
+{{- $name := default "task-processor" -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "api.service-account-name" -}}
+{{- $name := default .Values.api.serviceAccount -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+
+{{- define "app.chart" -}}
+{{- printf "%s-%s" .Values.appName .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{- define "api.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "api.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end -}}
+
+{{- define "api.labels" -}}
+helm.sh/chart: {{ include "app.chart" . }}
+{{ include "api.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
\ No newline at end of file
diff --git a/charts/tilegen-api/templates/tilegen/deployment.yaml b/charts/tilegen-api/templates/tilegen/deployment.yaml
new file mode 100644
index 00000000..da3c8d7b
--- /dev/null
+++ b/charts/tilegen-api/templates/tilegen/deployment.yaml
@@ -0,0 +1,147 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "api.name" . }}
+ {{- with .Values.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+ labels:
+ {{- include "api.labels" . | nindent 4 }}
+ {{- with .Values.labels }}
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
+ {{- if .Values.strategy }}
+ strategy:
+ {{- toYaml .Values.strategy | nindent 4 }}
+ {{- end }}
+ selector:
+ matchLabels:
+ {{- include "api.selectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ annotations:
+ checksum/secret: {{ include (print $.Template.BasePath "/tilegen/secrets.yaml") . | sha256sum }}
+ {{- with .Values.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "api.labels" . | nindent 8 }}
+ {{- with .Values.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ spec:
+ {{- with .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- if .Values.priorityClassName }}
+ priorityClassName: {{ .Values.priorityClassName }}
+ {{- end }}
+ {{- with .Values.podSecurityContext }}
+ securityContext:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
+ serviceAccountName: {{ include "api.service-account-name" . }}
+ volumes:
+ - name: temp-volume
+ emptyDir: {}
+ containers:
+ - name: {{ include "api.name" . }}
+ image: {{ required "A valid .Values.dgctlDockerRegistry entry required" $.Values.dgctlDockerRegistry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ ports:
+ - name: http
+ containerPort: 8080
+ protocol: TCP
+ volumeMounts:
+ - mountPath: "{{ .Values.api.tempPath }}"
+ name: temp-volume
+ livenessProbe:
+ httpGet:
+ path: /health/live
+ port: http
+ failureThreshold: 5
+ initialDelaySeconds: 5
+ periodSeconds: 15
+ successThreshold: 1
+ timeoutSeconds: 5
+ readinessProbe:
+ httpGet:
+ path: /health/ready
+ port: http
+ failureThreshold: 3
+ initialDelaySeconds: 5
+ periodSeconds: 5
+ successThreshold: 1
+ timeoutSeconds: 5
+ startupProbe:
+ httpGet:
+ path: /health/live
+ port: http
+ failureThreshold: 20
+ initialDelaySeconds: 5
+ periodSeconds: 5
+ timeoutSeconds: 5
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ lifecycle:
+ preStop:
+ exec:
+ command: ["/bin/sh", "-c", "sleep 5"]
+ env:
+ - name: DEBUG
+ value: "{{ .Values.api.debug }}"
+ - name: Processor__JobName
+ value: {{ include "task-processor-job.name" . }}
+ - name: Common__TempPath
+ value: "{{ .Values.api.tempPath }}"
+ - name: Common__AllowAnyOrigin
+ value: "{{ .Values.api.allowAnyOrigin }}"
+ - name: S3__Url
+ value: {{ required "A valid .Values.s3.host entry required" $.Values.s3.host }}
+ - name: S3__VectorTilesBucket
+ value: {{ required "A valid .Values.s3.vectorTilesBucket entry required" $.Values.s3.vectorTilesBucket }}
+ - name: S3__AccessKey
+ valueFrom:
+ secretKeyRef:
+ key: s3AccessKey
+ name: {{ include "api.name" . }}-secret
+ - name: S3__SecretKey
+ valueFrom:
+ secretKeyRef:
+ key: s3SecretKey
+ name: {{ include "api.name" . }}-secret
+ - name: Redis__Host
+ value: {{ required "A valid .Values.redis.host entry required" $.Values.redis.host }}
+ - name: Redis__Port
+ value: "{{ .Values.redis.port }}"
+ - name: Redis__DatabaseId
+ value: "{{ .Values.redis.databaseId }}"
+ - name: Redis__Username
+ value: {{ $.Values.redis.username }}
+ {{ if .Values.redis.password }}
+ - name: Redis__Password
+ valueFrom:
+ secretKeyRef:
+ key: redisPassword
+ name: {{ include "api.name" . }}-secret
+ {{- end }}
+ - name: Common__Logging__Format
+ value: "{{ .Values.api.logging.format }}"
diff --git a/charts/tilegen-api/templates/tilegen/ingress.yaml b/charts/tilegen-api/templates/tilegen/ingress.yaml
new file mode 100644
index 00000000..ab674099
--- /dev/null
+++ b/charts/tilegen-api/templates/tilegen/ingress.yaml
@@ -0,0 +1,41 @@
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "api.name" . -}}
+{{- $svcPort := .Values.service.port -}}
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: {{ $fullName }}
+ labels:
+ {{- include "api.labels" . | nindent 4 }}
+ {{- with .Values.ingress.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ ingressClassName: {{ .Values.ingress.className }}
+ {{- if .Values.ingress.tls }}
+ tls:
+ {{- range .Values.ingress.tls }}
+ - hosts:
+ {{- range .hosts }}
+ - {{ . | quote }}
+ {{- end }}
+ secretName: {{ .secretName }}
+ {{- end }}
+ {{- end }}
+ rules:
+ {{- range .Values.ingress.hosts }}
+ - host: {{ .host | quote }}
+ http:
+ paths:
+ {{- range .paths }}
+ - path: {{ .path }}
+ pathType: {{ .pathType }}
+ backend:
+ service:
+ name: {{ $fullName }}
+ port:
+ number: {{ $svcPort }}
+ {{- end }}
+ {{- end }}
+{{- end }}
diff --git a/charts/tilegen-api/templates/tilegen/role.yaml b/charts/tilegen-api/templates/tilegen/role.yaml
new file mode 100644
index 00000000..68f7c406
--- /dev/null
+++ b/charts/tilegen-api/templates/tilegen/role.yaml
@@ -0,0 +1,32 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: {{ include "api.service-account-name" . }}-role
+rules:
+ - apiGroups:
+ - ""
+ resources:
+ - pods
+ verbs:
+ - get
+ - list
+ - create
+ - watch
+ - delete
+ - apiGroups:
+ - batch
+ resources:
+ - jobs
+ - cronjobs
+ verbs:
+ - get
+ - list
+ - create
+ - watch
+ - delete
+ - apiGroups:
+ - batch
+ resources:
+ - jobs/status
+ verbs:
+ - get
diff --git a/charts/tilegen-api/templates/tilegen/rolebinding.yaml b/charts/tilegen-api/templates/tilegen/rolebinding.yaml
new file mode 100644
index 00000000..f57647fb
--- /dev/null
+++ b/charts/tilegen-api/templates/tilegen/rolebinding.yaml
@@ -0,0 +1,11 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ name: {{ include "api.service-account-name" . }}-binding
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: Role
+ name: {{ include "api.service-account-name" . }}-role
+subjects:
+ - kind: ServiceAccount
+ name: {{ include "api.service-account-name" . }}
diff --git a/charts/tilegen-api/templates/tilegen/secrets.yaml b/charts/tilegen-api/templates/tilegen/secrets.yaml
new file mode 100644
index 00000000..8fed1c18
--- /dev/null
+++ b/charts/tilegen-api/templates/tilegen/secrets.yaml
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: Secret
+metadata:
+ name: {{ include "api.name" . }}-secret
+type: Opaque
+data:
+ s3AccessKey: {{ required "Valid .Values.s3.accessKey required!" .Values.s3.accessKey | b64enc }}
+ s3SecretKey: {{ required "Valid .Values.s3.secretKey required!" .Values.s3.secretKey | b64enc }}
+ {{ if .Values.redis.password }}
+ redisPassword: {{ .Values.redis.password | b64enc }}
+ {{ end }}
\ No newline at end of file
diff --git a/charts/tilegen-api/templates/tilegen/service-account.yaml b/charts/tilegen-api/templates/tilegen/service-account.yaml
new file mode 100644
index 00000000..acff19d3
--- /dev/null
+++ b/charts/tilegen-api/templates/tilegen/service-account.yaml
@@ -0,0 +1,4 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "api.service-account-name" . }}
diff --git a/charts/tilegen-api/templates/tilegen/service.yaml b/charts/tilegen-api/templates/tilegen/service.yaml
new file mode 100644
index 00000000..ee35b312
--- /dev/null
+++ b/charts/tilegen-api/templates/tilegen/service.yaml
@@ -0,0 +1,25 @@
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "api.name" . }}
+ {{- if .Values.service.annotations }}
+ annotations:
+ {{- toYaml .Values.service.annotations | nindent 4 }}
+ {{- end }}
+ labels:
+ {{- include "api.labels" . | nindent 4 }}
+ {{- if .Values.service.labels }}
+ {{- toYaml .Values.service.labels | nindent 4 }}
+ {{- end }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ appProtocol: http
+ selector:
+ {{- include "api.selectorLabels" . | nindent 4 }}
diff --git a/charts/tilegen-api/templates/tilegen/task-processor-job.yaml b/charts/tilegen-api/templates/tilegen/task-processor-job.yaml
new file mode 100644
index 00000000..5b89fa18
--- /dev/null
+++ b/charts/tilegen-api/templates/tilegen/task-processor-job.yaml
@@ -0,0 +1,80 @@
+apiVersion: batch/v1
+kind: CronJob
+metadata:
+ name: {{ include "task-processor-job.name" . }}
+spec:
+ concurrencyPolicy: Forbid
+ schedule: "0 18 29 2 6"
+ suspend: true
+ successfulJobsHistoryLimit: {{ .Values.taskProcessor.successfulJobsHistoryLimit }}
+ jobTemplate:
+ spec:
+ backoffLimit: {{ .Values.taskProcessor.backoffLimit }}
+ activeDeadlineSeconds: 43200
+ template:
+ spec:
+ {{- with .Values.taskProcessor.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ restartPolicy: Never
+ parallelism: "{{ .Values.taskProcessor.maxParallelJobs }}"
+ serviceAccountName: {{ include "api.service-account-name" . }}
+ volumes:
+ - name: temp-volume
+ {{- if gt (len .Values.taskProcessor.tempVolume) 0 }}
+ {{- toYaml .Values.taskProcessor.tempVolume | nindent 14 }}
+ {{- else }}
+ {{- fail "A valid .Values.taskProcessor.tempVolume entry is required and must not be empty" }}
+ {{- end }}
+ containers:
+ - name: {{ include "task-processor-job.name" . }}
+ image: {{ required "A valid .Values.dgctlDockerRegistry entry required" $.Values.dgctlDockerRegistry }}/{{ .Values.taskProcessor.repository }}:{{ .Values.taskProcessor.tag }}
+ imagePullPolicy: IfNotPresent
+ resources:
+ {{- toYaml .Values.taskProcessor.resources | nindent 16 }}
+ volumeMounts:
+ - mountPath: "{{ .Values.api.tempPath }}"
+ name: temp-volume
+ env:
+ - name: Common__TempPath
+ value: "{{ .Values.api.tempPath }}"
+ - name: MODE
+ value: "Skip"
+ - name: S3__Url
+ value: {{ required "A valid .Values.s3.host entry required" $.Values.s3.host }}
+ - name: S3__VectorTilesBucket
+ value: {{ required "A valid .Values.s3.vectorTilesBucket entry required" $.Values.s3.vectorTilesBucket }}
+ - name: S3__AccessKey
+ valueFrom:
+ secretKeyRef:
+ key: s3AccessKey
+ name: {{ include "api.name" . }}-secret
+ - name: S3__SecretKey
+ valueFrom:
+ secretKeyRef:
+ key: s3SecretKey
+ name: {{ include "api.name" . }}-secret
+ - name: API_URL
+ value: http://{{ include "api.name" . }}
+ - name: Common__Logging__Format
+ value: "{{ .Values.api.logging.format }}"
+ - name: TileServer__Importer__Secure
+ value: "{{ .Values.tilesImporter.secure }}"
+ - name: TileServer__Importer__Hosts
+ value: {{ required "A valid .Values.tilesImporter.hosts entry required" $.Values.tilesImporter.hosts }}
+ - name: Redis__Host
+ value: {{ required "A valid .Values.redis.host entry required" $.Values.redis.host }}
+ - name: Redis__Port
+ value: "{{ .Values.redis.port }}"
+ - name: Redis__DatabaseId
+ value: "{{ .Values.redis.databaseId }}"
+ - name: Redis__Username
+ value: {{ $.Values.redis.username }}
+ {{ if .Values.redis.password }}
+ - name: Redis__Password
+ valueFrom:
+ secretKeyRef:
+ key: redisPassword
+ name: {{ include "api.name" . }}-secret
+ {{ end }}
diff --git a/charts/tilegen-api/templates/tilegen/vpa.yaml b/charts/tilegen-api/templates/tilegen/vpa.yaml
new file mode 100644
index 00000000..9c436e3e
--- /dev/null
+++ b/charts/tilegen-api/templates/tilegen/vpa.yaml
@@ -0,0 +1,30 @@
+{{- if .Values.vpa.enabled }}
+---
+
+apiVersion: autoscaling.k8s.io/v1
+kind: VerticalPodAutoscaler
+metadata:
+ name: {{ include "api.name" . }}
+ labels:
+ {{- include "api.labels" . | nindent 4 }}
+spec:
+ targetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: {{ include "api.name" . }}
+ updatePolicy:
+ updateMode: {{ .Values.vpa.updateMode }}
+ resourcePolicy:
+ containerPolicies:
+ - containerName: {{ .Chart.Name }}
+ controlledValues: RequestsOnly
+ mode: Auto
+ {{- with .Values.vpa.minAllowed }}
+ minAllowed:
+ {{- toYaml . | nindent 10 }}
+ {{- end }}
+ {{- with .Values.vpa.maxAllowed }}
+ maxAllowed:
+ {{- toYaml . | nindent 10 }}
+ {{- end }}
+{{- end }}
diff --git a/charts/tilegen-api/values.yaml b/charts/tilegen-api/values.yaml
new file mode 100644
index 00000000..42f82314
--- /dev/null
+++ b/charts/tilegen-api/values.yaml
@@ -0,0 +1,216 @@
+# @section Docker Registry settings
+
+# @param dgctlDockerRegistry Docker Registry endpoint where On-Premise services' images reside. Format: `host:port`.
+
+dgctlDockerRegistry: ''
+
+# @section **Common settings**
+# @param appName Name of the service.
+# @param replicaCount A replica count for the pod.
+# @param imagePullSecrets Kubernetes image pull secrets.
+# @param nameOverride Base name to use in all the Kubernetes entities deployed by this chart.
+# @param fullnameOverride Base fullname to use in all the Kubernetes entities deployed by this chart.
+# @param nodeSelector Kubernetes [node selectors](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector).
+# @param affinity Kubernetes pod [affinity settings](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity).
+# @param priorityClassName Kubernetes [pod priority](https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/).
+# @param terminationGracePeriodSeconds Kubernetes [termination grace period](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/).
+# @param tolerations Kubernetes [tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) settings.
+# @param podAnnotations Kubernetes [pod annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/).
+# @param podLabels Kubernetes [pod labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/).
+# @param annotations Kubernetes [annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/).
+# @param labels Kubernetes [labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/).
+# @param revisionHistoryLimit Revision history limit (used for [rolling back](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) a deployment).
+
+
+appName: tilegen-api
+replicaCount: 1
+imagePullSecrets: []
+nameOverride: ''
+fullnameOverride: ''
+nodeSelector: {}
+affinity: {}
+priorityClassName: ''
+terminationGracePeriodSeconds: 60
+tolerations: []
+podAnnotations: {}
+podLabels: {}
+annotations: {}
+labels: {}
+revisionHistoryLimit: 3
+
+# @extra Strategy settings
+
+# @param strategy.type Type of Kubernetes deployment. Can be `Recreate` or `RollingUpdate`.
+# @param strategy.rollingUpdate.maxUnavailable Maximum number of pods that can be created over the desired number of pods when doing [rolling update](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-update-deployment).
+# @param strategy.rollingUpdate.maxSurge Maximum number of pods that can be unavailable during the [rolling update](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-update-deployment) process.
+
+strategy:
+ type: RollingUpdate
+ rollingUpdate:
+ maxUnavailable: 0
+ maxSurge: 1
+
+# @extra Service settings
+
+# @param service.annotations Kubernetes [service annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/)
+# @param service.labels Kubernetes [service labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/).
+# @param service.type Kubernetes [service type](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types).
+# @param service.port PRO API service port.
+
+service:
+ annotations: {}
+ labels: {}
+ type: ClusterIP
+ port: 80
+
+# @extra Kubernetes [Vertical Pod Autoscaling](https://github.com/kubernetes/autoscaler/blob/master/vertical-pod-autoscaler/README.md) settings
+
+# @param vpa.enabled If VPA is enabled for the service.
+# @param vpa.updateMode VPA [update mode](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler#quick-start).
+# @param vpa.minAllowed.cpu Lower limit for the number of CPUs to which the autoscaler can scale down.
+# @param vpa.minAllowed.memory Lower limit for the RAM size to which the autoscaler can scale down.
+# @param vpa.maxAllowed.cpu Upper limit for the number of CPUs to which the autoscaler can scale up.
+# @param vpa.maxAllowed.memory Upper limit for the RAM size to which the autoscaler can scale up.
+
+vpa:
+ enabled: false
+ updateMode: Auto
+ minAllowed:
+ cpu: 100m
+ memory: 256M
+ maxAllowed:
+ cpu: 1
+ memory: 1024M
+
+# @extra Deployment settings
+
+# @param image.repository Repository
+# @param image.tag Tag
+# @param image.pullPolicy Pull Policy
+
+image:
+ repository: 2gis-on-premise/tilegen-api
+ tag: 1.1.6
+ pullPolicy: IfNotPresent
+
+# @extra TileGen Storage configuration
+
+# @param s3.host S3 endpoint. Format: `host:port`. **Required**
+# @param s3.accessKey S3 access key for accessing the bucket. **Required**
+# @param s3.secretKey S3 secret key for accessing the bucket. **Required**
+# @param s3.vectorTilesBucket S3 bucket for storing vector tiles data. **Required**
+
+s3:
+ host: ''
+ accessKey: ''
+ secretKey: ''
+ vectorTilesBucket: ''
+
+# @extra TileGen Api configuration
+
+# @param api.serviceAccount Kubernetes service account
+# @param api.tempPath Path to directory used for temp data
+# @param api.allowAnyOrigin Cors policy: allow any origin to perform requests to pro-api service
+# @extra api.logging Logging settings
+# @param api.logging.format Log message format, possible options: 'default' - compact json, 'renderedCompactJson' - rendered json format, 'simple' - plain text
+# @param api.logging.targets Collection of logging targets divided by comma. Currently only 'console' and 'database' are supported. Console is used by default (no need to specify).
+
+api:
+ serviceAccount: runner
+ tempPath: /tmp
+ allowAnyOrigin: false
+ logging:
+ format: simple
+ targets: ''
+
+# @extra Redis settings (supported version 6.x)
+
+# @param redis.host Redis host address. **Required**
+# @param redis.port Redis port. **Required**
+# @skip redis.databaseId
+# @param redis.username Username used to connect to Redis
+# @param redis.password Password used to connect to Redis
+
+redis:
+ host: ''
+ port: 6379
+ databaseId: 0
+ username: ''
+ password: ''
+
+# @extra Tile server importer settings
+
+# @param tilesImporter.secure Uses https protocol
+# @param tilesImporter.hosts Comma separated tile server importer hosts. Example: `tiles1.importer.host,tiles2.importer.host` **Required**
+tilesImporter:
+ secure: false
+ hosts: ''
+
+# @extra TileGen processor job settings
+
+# @param taskProcessor.repository Docker Repository Image.
+# @param taskProcessor.tag Docker image tag.
+# @param taskProcessor.backoffLimit The number of [retries](https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-backoff-failure-policy) before considering a Job as failed.
+# @param taskProcessor.successfulJobsHistoryLimit How many completed and failed jobs should be kept. See [docs](https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/#jobs-history-limits).
+# @param taskProcessor.nodeSelector Kubernetes [node selectors](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector).
+# @param taskProcessor.tempVolume Temporary data storage volume
+# @extra taskProcessor.resources **Limits for the tile processor job**
+# @param taskProcessor.resources.requests.cpu A CPU request.
+# @param taskProcessor.resources.requests.memory A memory request.
+# @param taskProcessor.resources.limits.cpu A CPU limit.
+# @param taskProcessor.resources.limits.memory A memory limit.
+# @param taskProcessor.maxParallelJobs How many import jobs can be run simultaneously
+
+taskProcessor:
+ repository: 2gis-on-premise/tilegen-processor
+ tag: 1.1.6
+ backoffLimit: 1
+ successfulJobsHistoryLimit: 5
+ nodeSelector: {}
+ tempVolume: {}
+ resources:
+ requests:
+ cpu: 1
+ memory: 1Gi
+ limits:
+ cpu: 4
+ memory: 24Gi
+ maxParallelJobs: 1
+
+# @extra Limits
+
+# @extra resources **Limits for the application service**
+# @param resources.requests.cpu A CPU request.
+# @param resources.requests.memory A memory request.
+# @param resources.limits.cpu A CPU limit.
+# @param resources.limits.memory A memory limit.
+
+resources:
+ requests:
+ cpu: 400m
+ memory: 256M
+ limits:
+ cpu: 1
+ memory: 1024M
+
+# @extra Kubernetes [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) settings
+
+# @param ingress.enabled If Ingress is enabled for the service.
+# @param ingress.className Name of the Ingress controller class.
+# @param ingress.hosts[0].host Hostname for the Ingress service.
+# @param ingress.hosts[0].paths[0].path Path of the host for the Ingress service.
+# @param ingress.hosts[0].paths[0].pathType Type of the path for the Ingress service.
+# @param ingress.tls TLS configuration.
+
+ingress:
+ enabled: false
+ className: nginx
+ hosts:
+ - host: tilegen-api.host
+ paths:
+ - path: /
+ pathType: Prefix
+ tls: []
+ # - hosts:
+ # - tilegen-api.example.com
+ # secretName: secret.tls