Compare commits

...

93 Commits

Author SHA1 Message Date
e4e5e06aec ++ camunda legacy wait 2026-10-31 17:45:29 +03:00
9f2c6932d7 ++ camunda timeout 30m 2026-10-31 15:21:43 +03:00
ivan
cd94931c76 ++ merge feat/zitadel-setup: sarex-installer machine user
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 13:53:12 +05:00
ivan
104bde49c4 ++ 2026-10-29 18:23:28 +05:00
ivan
b61571a858 ++ 2026-10-29 17:36:35 +05:00
13b9ca8a9f ++ stand chart repo from vars 2026-10-29 15:05:47 +03:00
ivan
31bdc74c80 ++ 2026-10-29 16:11:54 +05:00
ivan
9f4801af68 ++ contour zitadel: sarex-installer machine user for zitadel-setup
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 15:32:27 +05:00
ivan
63b33aaafb ++ 2026-10-29 13:06:42 +05:00
ivan
fb52d422ca ++ 2026-10-29 12:37:46 +05:00
ivan
deb0d5f0eb ++ 2026-10-28 20:06:09 +05:00
1613172dd6 ++ contour kafka client sasl plaintext 2026-10-28 15:47:31 +03:00
b7c36a5348 ++ stand routing layer 2026-10-28 15:31:36 +03:00
0037411aae ++ stand camunda via vault 2026-10-28 15:18:25 +03:00
c23b51e2a5 infra: route GoAlert through VK Istio 2026-10-28 14:39:19 +03:00
448a994fd4 Merge branch 'master' of https://gitlab.sarex.io/infra/iac 2026-10-28 14:38:14 +03:00
Дмитрий Лавренчук
bfad13da2f Merge branch 'pdm/update-image-api-fix-copy' into 'master'
fix: image documentation updated

See merge request infra/iac!14
2026-10-28 10:36:26 +00:00
diamondrigido
f936f5ffb0 fix: image documentation updated 2026-10-28 12:31:00 +02:00
ivan
25b3536124 ++ 2026-10-28 14:51:22 +05:00
ivan
cdc2c34bca ++ 2026-10-28 14:39:15 +05:00
ivan
3b53a99371 ++ 2026-10-28 14:30:36 +05:00
ivan
aa3365cb0d ++ 2026-10-28 14:27:20 +05:00
ivan
7cf8b13f91 ++ 2026-10-28 14:00:45 +05:00
ivan
83bfd4e046 ++ 2026-10-28 13:32:52 +05:00
1c3525fc1b ++ stand platform layer zitadel 2026-10-28 11:15:41 +03:00
a3fa7ba4c0 ++ stand data layer 2026-10-28 10:37:30 +03:00
32e4cff59e ++ stand flux cancel stale health check 2026-10-28 10:33:19 +03:00
4a46bb6626 ++ contour cert-manager images 2026-10-28 10:33:19 +03:00
34cbe7c79e ++ stand mesh layer 2026-10-28 10:33:19 +03:00
ivan
ae911c7d38 ++ 2026-10-28 12:31:10 +05:00
ivan
bd4b6d4ea6 ++ 2026-10-28 12:02:22 +05:00
ivan
56ade56754 ++ 2026-10-28 11:48:59 +05:00
emelinda
8a3540ead7 Add CDE_API_ENABLED environment variable to api and filestream configurations 2026-10-28 08:32:37 +03:00
emelinda
3dadb7a87a Merge branch 'master' of gitlab.sarex.io:infra/iac 2026-10-28 08:30:59 +03:00
emelinda
fc8ddcb511 Add CDE_API_ENABLED environment variable to filestream and api configurations in d8-ugmk-prod 2026-10-28 08:30:40 +03:00
f5a217e793 ++ stand vault layer 2026-10-27 22:48:56 +03:00
eeb27c6e29 ++ slice jobs allow failure 2026-10-27 22:36:55 +03:00
0fb5374e06 ++ slice job per contour 2026-10-27 22:35:41 +03:00
0a81938175 ++ publish contour slices 2026-10-27 22:30:13 +03:00
84f2555494 ++ stand cluster and slicer 2026-10-27 22:30:13 +03:00
faa1dd2cac Merge branch 'task/PDM-2628_download_not_work_wb' into 'master'
fix: update image for filestream wb

See merge request infra/iac!13
2026-10-27 18:55:21 +00:00
diamondrigido
f4a19774a2 fix: update image for filestream wb 2026-10-27 20:11:28 +02:00
emelinda
f39a907a87 [Message]
Update `d8-ugmk-prod` frontend image to `workspaces-v2-frontend:contour_1b5d64e4` in patch configuration
2026-10-27 21:07:58 +03:00
c401cf0dcb Merge branch 'pdm/update_pdf_markings' into 'master'
fix: update pdf markings amqp

See merge request infra/iac!12
2026-10-27 14:16:42 +00:00
diamondrigido
1d349b1a8c fix: move bundle in documentations 2026-10-27 15:47:58 +02:00
ivan
f6d4c2face ++ 2026-10-27 18:07:06 +05:00
diamondrigido
6fda7834ce fix: incorect in asterus pdf markings amqp 2026-10-27 14:49:27 +02:00
diamondrigido
0d4befa985 fix: update pdf markings amqp 2026-10-27 14:48:29 +02:00
ivan
9f263a97f3 ++ 2026-10-27 16:51:18 +05:00
b6f164f85e ++ outline db secret from tf 2026-10-27 13:37:58 +03:00
5e10d54d67 ++ outline pg sslmode 2026-10-27 13:37:58 +03:00
f190a6efa5 Merge branch 'pdm/fix_env_and_doc' into 'master'
fix: output_topic

See merge request infra/iac!10
2026-10-27 10:01:08 +00:00
5bccce5815 Merge branch 'feature/outline-vk-infra' into 'master'
Outline в vk-infra

See merge request infra/iac!11
2026-10-27 09:36:50 +00:00
0c696d3a3e ++ valkey image override 2026-10-27 12:31:57 +03:00
Pavel Ershov
385abf1092
Outline в vk-infra
- infrastructure/outline/vk-infra: namespace, HelmRelease outline-valkey (valkey 0.1.0, standalone) и outline (outline 0.1.0, Outline 1.12.0)
- clusters/vk-infra: подключение outline/vk-infra
- istio-config/vk-infra: Certificate, Gateway и VirtualService для wiki.sarex.space

Секреты outline и outline-valkey созданы в кластере вручную.
2026-10-26 20:49:39 +03:00
diamondrigido
3f7628cc54 fix: output_topic 2026-10-26 18:35:40 +02:00
2182c09031 Merge branch 'feature/infra-3023-pm-wb-kafka-topics' into 'master'
wb/pm: явно задать KAFKA_TOPICS planning → message-hub-prod (INFRA-3023)

See merge request infra/iac!9
2026-10-26 14:33:35 +00:00
emelinda
e33eaa1db8 Merge branch 'master' of gitlab.sarex.io:infra/iac into feature/infra-3023-pm-wb-kafka-topics
# Conflicts:
#	apps/pm/wb/backend.yaml
#	apps/pm/wb/celery.yaml
2026-10-26 19:32:58 +05:00
emelinda
cb99195564 Merge remote-tracking branch 'origin/master' 2026-10-26 18:11:13 +05:00
emelinda
f5ea728d29 Add Kafka configuration to wb backend and Celery YAML files 2026-10-26 18:11:04 +05:00
f86336741b Merge branch 'pdm/fix_env_and_doc' into 'master'
fix: незначительные изменения

See merge request infra/iac!8
2026-10-26 13:07:53 +00:00
4448188464 wb/pm: pin KAFKA_TOPICS planning -> message-hub-prod (INFRA-3023)
pm on WB published to Kafka topic "pm" (stale .env mounted via subPath),
while message-hub consumes "message-hub-prod". PDF export of KSG hung in
PENDING because get_converted_file never reached message-hub.

Set KAFKA_TOPICS explicitly in backend and celery so env overrides .env,
same as prod, d8-ugmk-prod, uralkal and vad.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01173KBT2kTwhxrzr2t3KutB
2026-10-26 12:49:31 +00:00
diamondrigido
af56004006 fix: незначительные изменения
1. Изменения базового образа для документации, чтоб копирование работало
2. output_navis env для wb engine
2026-10-26 13:49:08 +02:00
af112cfffe ++ srx ui kit pages 2026-10-26 14:42:34 +03:00
ivan
03eb83b362 ++ 2026-10-26 14:09:35 +05:00
ivan
a8716d51b3 ++ 2026-10-26 13:55:03 +05:00
ivan
a71b15ae18 ++ 2026-10-26 13:39:04 +05:00
ivan
a2f6a234cb ++ 2026-10-26 13:35:49 +05:00
ivan
6b5e2b7a1f ++ 2026-10-26 13:26:00 +05:00
ivan
5cbcdd4ff7 ++ 2026-10-26 13:07:14 +05:00
36b63ef189 ++ vk lb new fip 2026-10-26 10:56:02 +03:00
emelinda
4727e26c70 Update wb backend resource limits and service host references for consistency and performance 2026-10-26 11:48:24 +05:00
emelinda
91d6aa41d6 Add HelmRelease for pdf-markings-amqp in d8-ugmk-prod and update kustomization configuration 2026-10-26 09:53:21 +05:00
ivan
b3a1fe63c2 ++ 2026-10-24 12:53:11 +05:00
ivan
10d962dce5 ++ 2026-10-24 12:30:16 +05:00
ivan
3cfe74c301 ++ 2026-10-24 12:18:37 +05:00
ivan
c36406209f issues: SAREX_API from env, in-cluster Django in uralkal, vad, ugmk
The base production.py hardcoded SAREX_API = https://srx.wb.ru, ignoring the
env, so issue export (GET /api/core/users/<id>/) failed from closed contours
with CERTIFICATE_VERIFY_FAILED. Read it from SAREX_API with the old value as
default; wb keeps it.

uralkal, vad, d8-ugmk-prod: SAREX_API -> backend-svc.django:80 (server-side
calls, no TLS), and SAREX_HOST set to the contour's public host so links in
exports and notifications stay external.
2026-10-24 12:01:25 +05:00
emelinda
314d2103d0 Update wb Istio configuration: add CORS settings for https://srx.wb.ru and https://lk.srx.wb.ru 2026-10-23 18:13:26 +05:00
emelinda
ced8b7bc04 Update wb configurations: increase filestream resource limits, fix BIM_API_URL references, and add Istio routing for /bimv2/api/ 2026-10-23 18:09:28 +05:00
ivan
7d25e214cd ++ 2026-10-23 17:06:06 +05:00
ivan
934241a9b1 premises/d8-ugmk-prod: privileged pod-policy on the namespace
Deckhouse admission-policy-engine (baseline) rejected the pods because
istio-init needs NET_ADMIN and NET_RAW. Label the namespace
security.deckhouse.io/pod-policy=privileged like the other app namespaces in
ugmk.
2026-10-23 16:38:08 +05:00
ivan
54c036b23e premises in ugmk, inspections VS name fix, remarks contour image, debug pod sleep
premises: d8-ugmk-prod overlay (ugmk Kafka CA mounted, prod-sized requests
dropped), wired into the cluster, /premises/api/ routed on sarex.uralmine.com.
Terraform side is infra/terraform 856ab54.

istio-config d8-ugmk-prod, vad, uralkal: inspections-api reused the name
flows-api-virt-service, so two VirtualServices collided and one of
/flows/api/ and /inspections/api/ was lost. It is now
inspections-api-virt-service.

remarks base frontend image -> remarks-frontend:contour_013c5091.
psql-tools-debug in uralkal sleeps forever so it can be exec'd into.
2026-10-23 16:07:19 +05:00
ivan
7dbefd16c9 ++ 2026-10-22 22:19:52 +05:00
ivan
30eb5c554f mapper/uralkal: own env with in-cluster addresses
The overlay inherited SaaS prod hosts from base (api.sarex.io, lk.sarex.io),
which fail TLS verification from the closed contour. Point documentations,
flows, django and notes at their uralkal services; REDIS_USE and TIMEOUT
unchanged.
2026-10-22 21:32:36 +05:00
ivan
005e88d91e drawings/uralkal: workflow env for DWG export
drawings-api builds its workflows client from WORKFLOW_HOST, which no cluster
set, so POST /internal/v1/exports failed with 'unsupported protocol scheme'.
Add WORKFLOW_HOST and the other export settings from the drawings-api chart
with uralkal service addresses (processing, drawings, attachments).
2026-10-22 21:25:53 +05:00
3a62bd4792 ++ spicedb vk prod 2026-10-22 14:32:24 +03:00
ivan
7fec316147 ++ 2026-10-22 15:42:52 +05:00
ivan
5e87556471 ++ 2026-10-22 15:13:08 +05:00
ivan
bbe4d60705 notes/uralkal: own env with in-cluster addresses
The overlay inherited base env copied from SaaS prod: DJANGO_HOST
https://lk.sarex.io, workspaces/workflows on api.sarex.io and PG_SSL_MODE
verify-full. From the closed contour every request to django failed with
CERTIFICATE_VERIFY_FAILED. Point django, workspaces and workflows at their
uralkal services, attachments at its real port 8000, disable postgres SSL
(the uralkal server has none). FAAS_SERVICE and RESOURCE_URL stay as in base:
neither service exists in uralkal.
2026-10-22 14:41:39 +05:00
de5992a73a ++ vk business domains 2026-10-22 10:53:27 +03:00
ivan
d8ed05e07f attachments/uralkal: S3 endpoint straight to MinIO
YANDEX_S3_ENDPOINT_URL 10.133.0.245:9000 instead of s3-proxy, same as
documentations; the minioadmin credentials come from minio/apps/attachments
(terraform contour).
2026-10-22 12:41:35 +05:00
ivan
e0dcd7372c ++ 2026-10-22 11:26:49 +05:00
ivan
0c651d3d92 comparisons/uralkal: own tasks-execution-config
Overrides the base tasks-execution-config-comparisons-v2 ConfigMap (mounted
at /etc/app/tasks-execution-config.json) for uralkal: all 16 workflow tasks
run on the k8s executor with 2 CPU / 4Gi requests.
2026-10-22 00:55:17 +05:00
107 changed files with 11992 additions and 374 deletions

View File

@ -4,6 +4,8 @@ include:
stages:
- build
- slices
- slices-publish
variables:
RELEASE_NAME: iac-offline
@ -33,3 +35,31 @@ build_offline_mirror:
- docker push ${IMAGE_NAME}
- docker push ${CR}/${RELEASE_NAME}:latest
timeout: 30m
generate_slice_jobs:
stage: slices
image: ${CR}/infra/slice-builder:1.0.0
tags:
- build
rules:
- if: $CI_COMMIT_TAG =~ /^v?(?:\d+\.){2}\d+$/
variables:
GIT_DEPTH: "1"
script:
- python3 ci/publish-slice.py generate --release "$CI_COMMIT_TAG" --commit "$CI_COMMIT_SHA" --out slices-pipeline.yml
- cat slices-pipeline.yml
artifacts:
paths:
- slices-pipeline.yml
publish_contour_slices:
stage: slices-publish
rules:
- if: $CI_COMMIT_TAG =~ /^v?(?:\d+\.){2}\d+$/
needs:
- generate_slice_jobs
trigger:
include:
- artifact: slices-pipeline.yml
job: generate_slice_jobs
strategy: depend

View File

@ -24,7 +24,7 @@ spec:
vault.hashicorp.com/agent-inject-secret-attachments-s3: secrets/data/minio/apps/attachments
vault.hashicorp.com/agent-inject-template-attachments-s3: |-
{{- with secret "secrets/data/minio/apps/attachments" -}}
YANDEX_S3_ENDPOINT_URL=s3-proxy.s3-proxy.svc.cluster.local
YANDEX_S3_ENDPOINT_URL=10.133.0.245:9000
YANDEX_S3_ACCESS_KEY_ID={{ index .Data.data "access_key" }}
YANDEX_S3_SECRET_ACCESS_KEY={{ index .Data.data "secret_key" }}
YANDEX_S3_USE_SSL=false

View File

@ -3,6 +3,10 @@ kind: Kustomization
resources:
- ../base
patches:
- path: tasks-execution-config.yaml
target:
kind: ConfigMap
name: tasks-execution-config-comparisons-v2
- path: backend.yaml
target:
kind: HelmRelease

View File

@ -0,0 +1,122 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: tasks-execution-config-comparisons-v2
namespace: comparisons
data:
tasks-execution-config-comparisons-v2.json: |
{
"abap": {
"executor": "k8s",
"resources": {
"cpu_requests": "2",
"memory_requests": "4Gi"
}
},
"bim2bim_comparison": {
"executor": "k8s",
"resources": {
"cpu_requests": "2",
"memory_requests": "4Gi"
}
},
"bim_api_metadata_inserter_v2": {
"executor": "k8s",
"resources": {
"cpu_requests": "2",
"memory_requests": "4Gi"
}
},
"bim_api_metadata_inserter_v4": {
"executor": "k8s",
"resources": {
"cpu_requests": "2",
"memory_requests": "4Gi"
}
},
"bim_abap_updater": {
"executor": "k8s",
"resources": {
"cpu_requests": "2",
"memory_requests": "4Gi"
}
},
"build_ooc": {
"executor": "k8s",
"resources": {
"cpu_requests": "2",
"memory_requests": "4Gi"
}
},
"calculate_deviation_job": {
"executor": "k8s",
"resources": {
"cpu_requests": "2",
"memory_requests": "4Gi"
}
},
"cloud_to_cloud": {
"executor": "k8s",
"resources": {
"cpu_requests": "2",
"memory_requests": "4Gi"
}
},
"cloud_to_surface": {
"executor": "k8s",
"resources": {
"cpu_requests": "2",
"memory_requests": "4Gi"
}
},
"convert_to_potree": {
"executor": "k8s",
"resources": {
"cpu_requests": "2",
"memory_requests": "4Gi"
}
},
"deviation_icp": {
"executor": "k8s",
"resources": {
"cpu_requests": "2",
"memory_requests": "4Gi"
}
},
"las_to_tiff": {
"executor": "k8s",
"resources": {
"cpu_requests": "2",
"memory_requests": "4Gi"
}
},
"pdf_cv_comparer": {
"executor": "k8s",
"resources": {
"cpu_requests": "2",
"memory_requests": "4Gi"
}
},
"pdf_georeferencing": {
"executor": "k8s",
"resources": {
"cpu_requests": "2",
"memory_requests": "4Gi"
}
},
"split_pdf_document": {
"executor": "k8s",
"resources": {
"cpu_requests": "2",
"memory_requests": "4Gi"
}
},
"webhook_caller": {
"executor": "k8s",
"resources": {
"cpu_requests": "2",
"memory_requests": "4Gi"
}
}
}

View File

@ -18,7 +18,8 @@ spec:
spec:
containers:
- name: debug
image: cr.yandex/crp3ccidau046kdj8g9q/mc-files:dev7
image: cr.yandex/crp3ccidau046kdj8g9q/mc-files:dev5
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c", "while true; do sleep 3600; done"]
imagePullSecrets:
- name: regcred

View File

@ -305,6 +305,11 @@ data:
"uri": "/management/projects"
},
{
"name": "Справочники",
"uri": "/assets"
},
# {
# "name": "Обзор",
# "uri": "/projects"

View File

@ -8,6 +8,9 @@ spec:
values:
services:
backend:
deployment:
replicaCount:
_default: 2
envs:
- name: ALLOWED_HOSTS
value:

File diff suppressed because one or more lines are too long

View File

@ -36,7 +36,7 @@ spec:
image:
name:
_default: cr.yandex/crp3ccidau046kdj8g9q/pdf-markings-amqp:prod_3ab263be
_default: cr.yandex/crp3ccidau046kdj8g9q/pdf-markings-amqp:prod_9dea5b64
pullPolicy:
_default: IfNotPresent

View File

@ -65,7 +65,7 @@ spec:
enabled: false
image:
name:
_default: cr.yandex/crp3ccidau046kdj8g9q/documentations:prod_179e518c
_default: cr.yandex/crp3ccidau046kdj8g9q/documentations:prod_89c8039a
pullPolicy:
_default: IfNotPresent
service:
@ -89,6 +89,9 @@ spec:
- name: POSTGRES_POOL_SIZE
value:
_default: "20"
- name: CDE_API_ENABLED
value:
_default: "false"
- name: USE_LEGACY_BIM_FLOW
value:
_default: "true"
@ -236,6 +239,9 @@ spec:
- name: VALKEY_PORT
value:
_default: "6379"
- name: CDE_API_ENABLED
value:
_default: "false"
podAnnotations:
_default:
traffic.sidecar.istio.io/excludeOutboundPorts: "8200"

View File

@ -97,6 +97,9 @@ spec:
- name: PUBLIC_LINK_FOLDER_CONNECTOR_ENABLED
value:
_default: "true"
- name: CDE_API_ENABLED
value:
_default: "false"
- name: USE_ZITADEL
value:
_default: "1"
@ -223,6 +226,9 @@ spec:
- name: VALKEY_PORT
value:
_default: "6379"
- name: CDE_API_ENABLED
value:
_default: "false"
podAnnotations:
_default:
traffic.sidecar.istio.io/excludeOutboundPorts: "8200"

View File

@ -37,7 +37,7 @@ spec:
name:
_default: pdf-markings-amqp
replicaCount:
_default: 1
_default: 2
port:
_default: 8000
command:
@ -64,7 +64,7 @@ spec:
enabled: false
image:
name:
_default: cr.yandex/crp3ccidau046kdj8g9q/pdf-markings-amqp:prod_3ab263be
_default: cr.yandex/crp3ccidau046kdj8g9q/pdf-markings-amqp:prod_9dea5b64
pullPolicy:
_default: IfNotPresent
service:

View File

@ -156,3 +156,6 @@ spec:
- name: VALKEY_PORT
value:
_default: "6379"
- name: CDE_API_ENABLED
value:
_default: "false"

View File

@ -144,3 +144,6 @@ spec:
- name: VALKEY_PORT
value:
_default: "6379"
- name: CDE_API_ENABLED
value:
_default: "false"

View File

@ -12,4 +12,8 @@ patches:
- path: filestream.yaml
target:
kind: HelmRelease
name: documentations-filestream
name: documentations-filestream
- path: pdf-markings-amqp.yaml
target:
kind: HelmRelease
name: documentations-pdf-markings-amqp

View File

@ -0,0 +1,62 @@
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: documentations-pdf-markings-amqp
namespace: documentations
spec:
values:
services:
backend:
image:
name:
_default: cr.yandex/crp3ccidau046kdj8g9q/pdf-markings:contour_ce9ed6d7
envs:
- name: MARKS_APP__LOG_LEVEL
value:
_default: INFO
- name: MARKS_CRYPTO__HASHING_ALGO
value:
_default: md_gost12_256
- name: MARKS_QR__REDIRECT_URL
value:
_default: "https://sarex-stamp-verification.uralmine.com/"
- name: MARKS_QR__BASE_DOCUMENT_URL
value:
_default: "https://sarex.uralmine.com"
- name: MARKS_S3__REGION
value:
_default: ru-central1
- name: MARKS_S3__USE_SSL
value:
_default: "true"
- name: MARKS_S3__SSL_VERIFY
value:
_default: "false"
- name: MARKS_S3__DEFAULT_BUCKET
value:
_default: documentations-marks
- name: MARKS_RABBITMQ__ROUTING__INPUT_QUEUE
value:
_default: pdf_markings_input
- name: MARKS_RABBITMQ__HOST
value:
_default: rabbitmq.rabbitmq.svc.cluster.local
- name: MARKS_RABBITMQ__PORT
value:
_default: "5672"
- name: MARKS_RABBITMQ__HEARTBEAT_SECONDS
value:
_default: "60"

View File

@ -36,7 +36,7 @@ spec:
image:
name:
_default: cr.yandex/crp3ccidau046kdj8g9q/documentations:prod_98a23ef5
_default: cr.yandex/crp3ccidau046kdj8g9q/documentations:prod_0be18f51
pullPolicy:
_default: IfNotPresent
@ -134,6 +134,10 @@ spec:
- name: POSTGRES_POOL_SIZE
value:
_default: "20"
- name: CDE_API_ENABLED
value:
_default: "false"
- name: ZITADEL_ACCOUNT
value:
@ -215,9 +219,13 @@ spec:
value:
_default: "http://workspaces-service.workspaces.svc.cluster.local:8000/"
# Сервиса bim-api-service в контуре wb нет: в ns bim есть только
# backend-service:8000 (bim v2), на него же BIM_API_URL смотрит в
# brusnika-stage и asterus. Клиент bim-api (resty, retry 5 x 1s)
# на неразрешимом DNS отваливался ровно за ~5 с.
- name: BIM_API_URL
value:
_default: "http://bim-api-service.bim.svc.cluster.local:8080/"
_default: "http://backend-service.bim.svc.cluster.local:8000/"
- name: BIM_API_V2_URL
value:

View File

@ -36,7 +36,7 @@ spec:
image:
name:
_default: cr.yandex/crp3ccidau046kdj8g9q/documentations-api-files:prod_3f19a21d
_default: cr.yandex/crp3ccidau046kdj8g9q/documentations-api-files:prod_fef3add2
pullPolicy:
_default: IfNotPresent
@ -56,13 +56,16 @@ spec:
limits:
cpu:
_default: 639m
# Range-отдача BIM-моделей идёт стримом, но поверх неё работает
# gorilla CompressHandler (gzip), и все поды регулярно уходили
# в OOMKilled (exit 137) на 198Mi.
memory:
_default: 198Mi
_default: 512Mi
requests:
cpu:
_default: 50m
memory:
_default: 85Mi
_default: 128Mi
probes:
liveness:
@ -134,6 +137,10 @@ spec:
- name: API_ADDRESS
value:
_default: "0.0.0.0:8080"
- name: CDE_API_ENABLED
value:
_default: "false"
- name: API_ADDRESS_FILE
value:
@ -191,9 +198,13 @@ spec:
value:
_default: "http://workspaces-service.workspaces.svc.cluster.local:8000/"
# Сервиса bim-api-service в контуре wb нет: в ns bim есть только
# backend-service:8000 (bim v2), на него же BIM_API_URL смотрит в
# brusnika-stage и asterus. Клиент bim-api (resty, retry 5 x 1s)
# на неразрешимом DNS отваливался ровно за ~5 с.
- name: BIM_API_URL
value:
_default: "http://bim-api-service.bim.svc.cluster.local:8080/"
_default: "http://backend-service.bim.svc.cluster.local:8000/"
- name: BIM_API_V2_URL
value:

View File

@ -36,7 +36,7 @@ spec:
image:
name:
_default: cr.yandex/crp3ccidau046kdj8g9q/pdf-markings-amqp:prod_3ab263be
_default: cr.yandex/crp3ccidau046kdj8g9q/pdf-markings-amqp:prod_9dea5b64
pullPolicy:
_default: IfNotPresent

View File

@ -0,0 +1,46 @@
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: backend
namespace: drawings
spec:
values:
services:
backend:
envs:
- name: POSTGRES_POOL_SIZE
value:
_default: "3"
- name: API_ADDRESS
value:
_default: "0.0.0.0:8000"
- name: ENABLE_SSL
value:
_default: "0"
- name: WORKFLOW_HOST
value:
_default: "http://backend-svc.processing.svc.cluster.local/"
- name: IMAGE_NAME_EXPORT_TO_DWG
value:
_default: "cross-sections-to-dwg"
- name: IMAGE_TAG
value:
_default: "develop"
- name: TASK_VERSION
value:
_default: "1"
- name: DRAWING_INTERNAL_URL
value:
_default: "http://backend-service.drawings.svc.cluster.local:8000/"
- name: ATTACHMENT_URL
value:
_default: "http://attachments-service.attachments.svc.cluster.local:8000"

View File

@ -2,3 +2,8 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
patches:
- path: backend.yaml
target:
kind: HelmRelease
name: backend

View File

@ -18,7 +18,7 @@ data:
# DEBUG SETTINGS START
# ---------------------------------------------------------------------------------------------------------------------
DEBUG = True
DEBUG = False
ALLOWED_HOSTS = ['*']
# ---------------------------------------------------------------------------------------------------------------------
# DEBUG SETTINGS END

View File

@ -55,14 +55,14 @@ spec:
resources:
limits:
cpu:
_default: 23m
_default: "1"
memory:
_default: 506Mi
_default: 1Gi
requests:
cpu:
_default: 12m
_default: 100m
memory:
_default: 330Mi
_default: 512Mi
probes:
liveness:
@ -97,23 +97,23 @@ spec:
envs:
- name: BASE_HOST
value:
_default: "https://srx.wb.ru"
_default: "http://frontend-service.django.svc.cluster.local:80"
- name: DJANGO_HOST
value:
_default: "https://srx.wb.ru"
_default: "http://backend.django.svc.cluster.local:8000"
- name: REVIEWS_HOST
value:
_default: "https://srx.wb.ru/flows"
_default: "http://backend-service.flows.svc.cluster.local:8000"
- name: GATEWAY_HOST
value:
_default: "https://srx.wb.ru/gateway"
_default: "http://pdm-api.documentations.svc.cluster.local:8080"
- name: DOCUMENTATIONS_HOST
value:
_default: "https://srx.wb.ru/documentations"
_default: "http://documentations-api.documentations.svc.cluster.local:8080"
- name: EAV_HOST
value:
@ -151,6 +151,10 @@ spec:
value:
_default: "180"
- name: GUNICORN_CMD_ARGS
value:
_default: "--timeout 3600 --graceful-timeout 30"
commitSha: ""
gitlabUri: ""
gitlabJobUrl: ""

View File

@ -9,6 +9,8 @@ spec:
services:
backend:
deployment:
replicaCount:
_default: 2
args:
_default:
- |

View File

@ -0,0 +1,15 @@
---
apiVersion: v1
kind: Service
metadata:
name: iams
namespace: iam
spec:
type: ClusterIP
selector:
app: iam-backend
ports:
- name: http
port: 8080
targetPort: 8080
protocol: TCP

View File

@ -4,6 +4,7 @@ kind: Kustomization
namespace: iam
resources:
- ../base
- iams-service.yaml
patches:
- path: backend-s3.yaml
target:

View File

@ -0,0 +1,15 @@
---
apiVersion: v1
kind: Service
metadata:
name: iams
namespace: iam
spec:
type: ClusterIP
selector:
app: iam-backend
ports:
- name: http
port: 8080
targetPort: 8080
protocol: TCP

View File

@ -3,6 +3,7 @@ kind: Kustomization
namespace: iam
resources:
- ../base
- iams-service.yaml
patches:
- path: backend-s3.yaml
target:

View File

@ -42,7 +42,7 @@ spec:
image:
name:
_default: cr.yandex/crp3ccidau046kdj8g9q/sarex-inspections:production_5fcce90d
_default: cr.yandex/crp3ccidau046kdj8g9q/inspections-backend:contour_32f00e42
pullPolicy:
_default: IfNotPresent

View File

@ -122,7 +122,7 @@ data:
"PUT",
]
SAREX_API = "https://srx.wb.ru"
SAREX_API = os.getenv("SAREX_API", "https://srx.wb.ru")
AERO_PUBLIC_HOST = os.getenv("AERO_PUBLIC_HOST", default=SAREX_API)

View File

@ -108,6 +108,10 @@ spec:
# там SAREX_API переприсваивается после `from .base import *`.
# См. apps/issues/d8-ugmk-prod/production-configmap.yaml (INFRA-3005).
- name: SAREX_API
value:
_default: "http://backend-svc.django.svc.cluster.local:80"
- name: SAREX_HOST
value:
_default: "https://sarex.uralmine.com"

View File

@ -102,6 +102,10 @@ spec:
# Реально действует значение из production-configmap, см. там.
- name: SAREX_API
value:
_default: "http://backend-svc.django.svc.cluster.local:80"
- name: SAREX_HOST
value:
_default: "https://sarex.uralmine.com"

View File

@ -1,33 +1,5 @@
---
# ВНИМАНИЕ: data["production.py"] — одна строка, kustomize заменяет её ЦЕЛИКОМ,
# поэтому здесь продублировано всё содержимое из
# apps/issues/base/production-configmap.yaml (та же ловушка, что с envs).
#
# Зачем нужен этот патч:
# production.py делает `from .base import *` (там всё через os.getenv), а затем
# переприсваивает часть значений ХАРДКОДОМ — поэтому для этих переменных
# ConfigMap ПОБЕЖДАЕТ env из HelmRelease, и правка env в оверлее
# backend-s3.yaml/celery-s3.yaml сама по себе ни на что не влияет.
#
# INFRA-3005 (основная причина зависания экспорта в Excel):
# в base хардкодом WORKFLOWS_HOST/WORKFLOWS_URL = workflows-api-service.workflow
# — такого сервиса в УГМК нет. celery собирает xlsx, затем
# ExportFinishedNotification → issues/mailing.py:122 делает POST на
# {WORKFLOWS_HOST}/internal/v1/companies/{id}/workflows и падает с
# ConnectionError (Name or service not known) — задача фейлится, фронт не
# получает завершения и крутит загрузку бесконечно. Тем же путём с 26.08
# падали ВСЕ уведомления (send_notification_on_create/on_update/
# to_new_responsible/on_bulk_update, ~1770 ошибок).
#
# Отличия от base:
# - WORKFLOWS_HOST / WORKFLOWS_URL → backend-svc.processing (через os.getenv,
# чтобы env из оверлея снова начал работать)
# - SAREX_API → https://sarex.uralmine.com (в base зашит https://srx.wb.ru)
# - CORS/CSRF origins → https://sarex.uralmine.com (в base только lk.srx.wb.ru)
# - убраны хардкоды KAFKA_USERNAME/KAFKA_PASSWORD/DJANGO_TOKEN и чужой
# дефолт KAFKA_HOST: в УГМК всё это приходит из Vault
# (см. podAnnotations в backend-s3.yaml / celery-s3.yaml / kafka-app.yaml)
# - BASE_AERO_URL оставлен внутренним — он server-to-server
apiVersion: v1
kind: ConfigMap
metadata:
@ -146,9 +118,9 @@ data:
CORS_ALLOW_ALL_ORIGINS = True
ENABLE_MAILGUN=False
SMTP_PORT=465
SMTP_HOST="mail.rwb.ru"
EMAIL_FROM="sarex@rwb.ru"
SMTP_PORT=587
SMTP_HOST="post.uralmine.com"
EMAIL_FROM="sarex@uralmine.com"
CORS_ALLOW_METHODS = [
"DELETE",

View File

@ -1,149 +0,0 @@
---
# ВНИМАНИЕ: envs и args — списки, kustomize заменяет их ЦЕЛИКОМ (JSON merge patch),
# поэтому здесь продублирован весь набор из apps/issues/base/backend.yaml.
# podAnnotations — map, мержится по ключам.
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: backend
namespace: issues
spec:
values:
services:
backend:
deployment:
args:
_default:
- |
set -a
[ -f /vault/secrets/issues-db ] && . /vault/secrets/issues-db
[ -f /vault/secrets/issues-rabbitmq ] && . /vault/secrets/issues-rabbitmq
[ -f /vault/secrets/issues-s3 ] && . /vault/secrets/issues-s3
[ -f /vault/secrets/issues-django-auth ] && . /vault/secrets/issues-django-auth
[ -f /vault/secrets/issues-jwt-private ] && export JWT_PRIVATE_KEY="$(cat /vault/secrets/issues-jwt-private)"
[ -f /vault/secrets/issues-jwt-public ] && export JWT_PUBLIC_KEY="$(cat /vault/secrets/issues-jwt-public)"
[ -f /vault/secrets/issues-kafka ] && . /vault/secrets/issues-kafka
set +a
exec /src/entrypoint.sh
volumes:
_default:
- name: production-configmap
mountPath:
_default: /src/config/settings/production.py
subPath:
_default: production.py
readOnly:
_default: true
configMap:
name:
_default: production-configmap
items:
- key: production.py
path:
_default: production.py
- name: kafka-ca-cert
mountPath:
_default: /usr/local/share/ca-certificates/kafka.crt
subPath:
_default: kafka.crt
readOnly:
_default: true
secret:
secretName:
_default: kafka-kafka-contour-tls
items:
- key: ca.crt
path:
_default: kafka.crt
envs:
- name: ENVIRONMENT
value:
_default: "production"
- name: AERO_PUBLIC_HOST
value:
_default: "https://sarex.contour.infra.sarex.tech"
- name: AERO_HOST
value:
_default: "https://sarex.contour.infra.sarex.tech"
- name: BASE_AERO_URL
value:
_default: "https://sarex.contour.infra.sarex.tech"
- name: BASE_AUTH_URL
value:
_default: "http://backend-svc.django.svc.cluster.local:80"
- name: WORKFLOWS_HOST
value:
_default: "http://backend-svc.workflow.svc.cluster.local:80"
- name: WORKFLOWS_URL
value:
_default: "http://backend-svc.workflow.svc.cluster.local:80"
- name: RESOURCES_API_HOST
value:
_default: "http://iam-backend.iam.svc.cluster.local:8000"
- name: EAV_HOST
value:
_default: "http://backend-svc.eav.svc.cluster.local:80"
- name: SAREX_API
value:
_default: "https://sarex.contour.infra.sarex.tech"
- name: DOCUMENTATIONS_URL
value:
_default: "http://documentations-api-svc.documentations.svc.cluster.local:80"
- name: DJANGO_SETTINGS_MODULE
value:
_default: "config.settings.production"
- name: API_ADDRESS
value:
_default: "8000"
# Kafka — код (kafka_app/app.py) ждёт KAFKA_HOST единой строкой "host:port",
# KAFKA_SSL_CAFILE — путь к файлу (не PEM-текст, в отличие от flows-backend).
# Хост/порт/CA — те же проверенные значения, что у message-hub/pm/flows.
- name: KAFKA_HOST
value:
_default: "kafka-kafka-contour.kafka.svc.cluster.local:9092"
- name: KAFKA_SSL_CAFILE
value:
_default: "/usr/local/share/ca-certificates/kafka.crt"
# Топики совпадают с тем, что уже провижено на брокере (см. topics
# в секрете kafka/apps/pm) и с SETTINGS_TOPICS у message-hub.
- name: KAFKA_ISSUES_TOPIC
value:
_default: "issues_broadcast_prod"
- name: KAFKA_EAV_ASSETS_TOPIC
value:
_default: "assets_broadcast"
podAnnotations:
_default:
vault.hashicorp.com/agent-inject-secret-issues-s3: secrets/data/minio/apps/issues
vault.hashicorp.com/agent-inject-template-issues-s3: |-
{{- with secret "secrets/data/minio/apps/issues" -}}
YC_S3_ACCESS_KEY_ID={{ index .Data.data "access_key" }}
YC_S3_SECRET_ACCESS_KEY={{ index .Data.data "secret_key" }}
YC_S3_BUCKET_NAME=issues
YC_S3_ENDPOINT_URL=http://s3-proxy.s3-proxy.svc.cluster.local
{{- end -}}
vault.hashicorp.com/agent-inject-secret-issues-kafka: secrets/data/kafka/apps/issues
vault.hashicorp.com/agent-inject-template-issues-kafka: |-
{{- with secret "secrets/data/kafka/apps/issues" -}}
KAFKA_USERNAME={{ index .Data.data "username" }}
KAFKA_PASSWORD={{ index .Data.data "password" }}
{{- end -}}

View File

@ -8,8 +8,145 @@ spec:
values:
services:
backend:
image:
name:
_default: cr.yandex/crp3ccidau046kdj8g9q/issues:production_eb983275
deployment:
resources:
requests:
cpu: null
memory: null
args:
_default:
- |
set -a
[ -f /vault/secrets/issues-db ] && . /vault/secrets/issues-db
[ -f /vault/secrets/issues-rabbitmq ] && . /vault/secrets/issues-rabbitmq
[ -f /vault/secrets/issues-s3 ] && . /vault/secrets/issues-s3
[ -f /vault/secrets/issues-django-auth ] && . /vault/secrets/issues-django-auth
[ -f /vault/secrets/issues-jwt-private ] && export JWT_PRIVATE_KEY="$(cat /vault/secrets/issues-jwt-private)"
[ -f /vault/secrets/issues-jwt-public ] && export JWT_PUBLIC_KEY="$(cat /vault/secrets/issues-jwt-public)"
[ -f /vault/secrets/issues-kafka ] && . /vault/secrets/issues-kafka
set +a
exec /src/entrypoint.sh
volumes:
_default:
- name: production-configmap
mountPath:
_default: /src/config/settings/production.py
subPath:
_default: production.py
readOnly:
_default: true
configMap:
name:
_default: production-configmap
items:
- key: production.py
path:
_default: production.py
- name: kafka-ca-cert
mountPath:
_default: /usr/local/share/ca-certificates/kafka.crt
subPath:
_default: kafka.crt
readOnly:
_default: true
secret:
secretName:
_default: kafka-kafka-contour-tls
items:
- key: ca.crt
path:
_default: kafka.crt
envs:
- name: ENVIRONMENT
value:
_default: "production"
- name: AERO_PUBLIC_HOST
value:
_default: "https://sarex.contour.infra.sarex.tech"
- name: AERO_HOST
value:
_default: "https://sarex.contour.infra.sarex.tech"
- name: BASE_AERO_URL
value:
_default: "https://sarex.contour.infra.sarex.tech"
- name: BASE_AUTH_URL
value:
_default: "http://backend-svc.django.svc.cluster.local:80"
- name: WORKFLOWS_HOST
value:
_default: "http://backend-svc.workflow.svc.cluster.local:80"
- name: WORKFLOWS_URL
value:
_default: "http://backend-svc.workflow.svc.cluster.local:80"
- name: RESOURCES_API_HOST
value:
_default: "http://iam-backend.iam.svc.cluster.local:8000"
- name: EAV_HOST
value:
_default: "http://backend-svc.eav.svc.cluster.local:80"
- name: SAREX_API
value:
_default: "http://backend-svc.django.svc.cluster.local:80"
- name: SAREX_HOST
value:
_default: "https://sarex.local.uralkali.com"
- name: DOCUMENTATIONS_URL
value:
_default: "http://documentations-api-svc.documentations.svc.cluster.local:80"
- name: DJANGO_SETTINGS_MODULE
value:
_default: "config.settings.production"
- name: API_ADDRESS
value:
_default: "8000"
- name: KAFKA_HOST
value:
_default: "kafka-kafka-contour.kafka.svc.cluster.local:9092"
- name: KAFKA_SSL_CAFILE
value:
_default: "/usr/local/share/ca-certificates/kafka.crt"
- name: KAFKA_ISSUES_TOPIC
value:
_default: "issues_broadcast_prod"
- name: KAFKA_EAV_ASSETS_TOPIC
value:
_default: "assets_broadcast"
podAnnotations:
_default:
vault.hashicorp.com/agent-inject-secret-issues-s3: secrets/data/minio/apps/issues
vault.hashicorp.com/agent-inject-template-issues-s3: |-
{{- with secret "secrets/data/minio/apps/issues" -}}
YC_S3_ACCESS_KEY_ID={{ index .Data.data "access_key" }}
YC_S3_SECRET_ACCESS_KEY={{ index .Data.data "secret_key" }}
YC_S3_BUCKET_NAME=issues
YC_S3_ENDPOINT_URL=http://10.133.0.245:9000
{{- end -}}
vault.hashicorp.com/agent-inject-secret-issues-kafka: secrets/data/kafka/apps/issues
vault.hashicorp.com/agent-inject-template-issues-kafka: |-
{{- with secret "secrets/data/kafka/apps/issues" -}}
KAFKA_USERNAME={{ index .Data.data "username" }}
KAFKA_PASSWORD={{ index .Data.data "password" }}
{{- end -}}

View File

@ -1,145 +0,0 @@
---
# ВНИМАНИЕ: envs и args — списки, kustomize заменяет их ЦЕЛИКОМ (JSON merge patch),
# поэтому здесь продублирован весь набор из apps/issues/base/celery.yaml.
# podAnnotations — map, мержится по ключам.
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: celery
namespace: issues
spec:
values:
services:
celery:
deployment:
args:
_default:
- |
set -a
[ -f /vault/secrets/issues-db ] && . /vault/secrets/issues-db
[ -f /vault/secrets/issues-rabbitmq ] && . /vault/secrets/issues-rabbitmq
[ -f /vault/secrets/issues-s3 ] && . /vault/secrets/issues-s3
[ -f /vault/secrets/issues-django-auth ] && . /vault/secrets/issues-django-auth
[ -f /vault/secrets/issues-jwt-private ] && export JWT_PRIVATE_KEY="$(cat /vault/secrets/issues-jwt-private)"
[ -f /vault/secrets/issues-jwt-public ] && export JWT_PUBLIC_KEY="$(cat /vault/secrets/issues-jwt-public)"
[ -f /vault/secrets/issues-kafka ] && . /vault/secrets/issues-kafka
set +a
exec celery -A config worker -l info -E
volumes:
_default:
- name: production-configmap
mountPath:
_default: /src/config/settings/production.py
subPath:
_default: production.py
readOnly:
_default: true
configMap:
name:
_default: production-configmap
items:
- key: production.py
path:
_default: production.py
- name: kafka-ca-cert
mountPath:
_default: /usr/local/share/ca-certificates/kafka.crt
subPath:
_default: kafka.crt
readOnly:
_default: true
secret:
secretName:
_default: kafka-kafka-contour-tls
items:
- key: ca.crt
path:
_default: kafka.crt
envs:
- name: ENVIRONMENT
value:
_default: "production"
- name: AERO_PUBLIC_HOST
value:
_default: "https://srx.wb.ru"
- name: AERO_HOST
value:
_default: "https://srx.wb.ru"
- name: BASE_AERO_URL
value:
_default: "https://srx.wb.ru"
- name: BASE_AUTH_URL
value:
_default: "http://backend-svc.django.svc.cluster.local:80"
- name: WORKFLOWS_HOST
value:
_default: "http://workflows-api-service.workflow.svc.cluster.local:8000"
- name: WORKFLOWS_URL
value:
_default: "http://workflows-api-service.workflow.svc.cluster.local:8000"
- name: RESOURCES_API_HOST
value:
_default: "http://iam-backend.iam.svc.cluster.local:8000"
- name: EAV_HOST
value:
_default: "http://backend-svc.eav.svc.cluster.local:80"
- name: SAREX_API
value:
_default: "https://srx.wb.ru"
- name: DOCUMENTATIONS_URL
value:
_default: "http://backend-api-svc.documentations.svc.cluster.local:80"
- name: DJANGO_SETTINGS_MODULE
value:
_default: "config.settings.production"
- name: API_ADDRESS
value:
_default: "8000"
# См. подробные комментарии в apps/issues/d8-ugmk-prod/backend-s3.yaml.
- name: KAFKA_HOST
value:
_default: "kafka-kafka-contour.kafka.svc.cluster.local:9092"
- name: KAFKA_SSL_CAFILE
value:
_default: "/usr/local/share/ca-certificates/kafka.crt"
- name: KAFKA_ISSUES_TOPIC
value:
_default: "issues_broadcast_prod"
- name: KAFKA_EAV_ASSETS_TOPIC
value:
_default: "assets_broadcast"
podAnnotations:
_default:
vault.hashicorp.com/agent-inject-secret-issues-s3: secrets/data/minio/apps/issues
vault.hashicorp.com/agent-inject-template-issues-s3: |-
{{- with secret "secrets/data/minio/apps/issues" -}}
YC_S3_ACCESS_KEY_ID={{ index .Data.data "access_key" }}
YC_S3_SECRET_ACCESS_KEY={{ index .Data.data "secret_key" }}
YC_S3_BUCKET_NAME=issues
YC_S3_ENDPOINT_URL=http://s3-proxy.s3-proxy.svc.cluster.local
{{- end -}}
vault.hashicorp.com/agent-inject-secret-issues-kafka: secrets/data/kafka/apps/issues
vault.hashicorp.com/agent-inject-template-issues-kafka: |-
{{- with secret "secrets/data/kafka/apps/issues" -}}
KAFKA_USERNAME={{ index .Data.data "username" }}
KAFKA_PASSWORD={{ index .Data.data "password" }}
{{- end -}}

View File

@ -13,3 +13,137 @@ spec:
requests:
cpu: null
memory: null
args:
_default:
- |
set -a
[ -f /vault/secrets/issues-db ] && . /vault/secrets/issues-db
[ -f /vault/secrets/issues-rabbitmq ] && . /vault/secrets/issues-rabbitmq
[ -f /vault/secrets/issues-s3 ] && . /vault/secrets/issues-s3
[ -f /vault/secrets/issues-django-auth ] && . /vault/secrets/issues-django-auth
[ -f /vault/secrets/issues-jwt-private ] && export JWT_PRIVATE_KEY="$(cat /vault/secrets/issues-jwt-private)"
[ -f /vault/secrets/issues-jwt-public ] && export JWT_PUBLIC_KEY="$(cat /vault/secrets/issues-jwt-public)"
[ -f /vault/secrets/issues-kafka ] && . /vault/secrets/issues-kafka
set +a
exec celery -A config worker -l info -E
volumes:
_default:
- name: production-configmap
mountPath:
_default: /src/config/settings/production.py
subPath:
_default: production.py
readOnly:
_default: true
configMap:
name:
_default: production-configmap
items:
- key: production.py
path:
_default: production.py
- name: kafka-ca-cert
mountPath:
_default: /usr/local/share/ca-certificates/kafka.crt
subPath:
_default: kafka.crt
readOnly:
_default: true
secret:
secretName:
_default: kafka-kafka-contour-tls
items:
- key: ca.crt
path:
_default: kafka.crt
envs:
- name: ENVIRONMENT
value:
_default: "production"
- name: AERO_PUBLIC_HOST
value:
_default: "https://sarex.contour.infra.sarex.tech"
- name: AERO_HOST
value:
_default: "https://sarex.contour.infra.sarex.tech"
- name: BASE_AERO_URL
value:
_default: "https://sarex.contour.infra.sarex.tech"
- name: BASE_AUTH_URL
value:
_default: "http://backend-svc.django.svc.cluster.local:80"
- name: WORKFLOWS_HOST
value:
_default: "http://workflows-api-service.workflow.svc.cluster.local:8000"
- name: WORKFLOWS_URL
value:
_default: "http://workflows-api-service.workflow.svc.cluster.local:8000"
- name: RESOURCES_API_HOST
value:
_default: "http://iam-backend.iam.svc.cluster.local:8000"
- name: EAV_HOST
value:
_default: "http://backend-svc.eav.svc.cluster.local:80"
- name: SAREX_API
value:
_default: "http://backend-svc.django.svc.cluster.local:80"
- name: SAREX_HOST
value:
_default: "https://sarex.local.uralkali.com"
- name: DOCUMENTATIONS_URL
value:
_default: "http://backend-api-svc.documentations.svc.cluster.local:80"
- name: DJANGO_SETTINGS_MODULE
value:
_default: "config.settings.production"
- name: API_ADDRESS
value:
_default: "8000"
- name: KAFKA_HOST
value:
_default: "kafka-kafka-contour.kafka.svc.cluster.local:9092"
- name: KAFKA_SSL_CAFILE
value:
_default: "/usr/local/share/ca-certificates/kafka.crt"
- name: KAFKA_ISSUES_TOPIC
value:
_default: "issues_broadcast_prod"
- name: KAFKA_EAV_ASSETS_TOPIC
value:
_default: "assets_broadcast"
podAnnotations:
_default:
vault.hashicorp.com/agent-inject-secret-issues-s3: secrets/data/minio/apps/issues
vault.hashicorp.com/agent-inject-template-issues-s3: |-
{{- with secret "secrets/data/minio/apps/issues" -}}
YC_S3_ACCESS_KEY_ID={{ index .Data.data "access_key" }}
YC_S3_SECRET_ACCESS_KEY={{ index .Data.data "secret_key" }}
YC_S3_BUCKET_NAME=issues
YC_S3_ENDPOINT_URL=http://10.133.0.245:9000
{{- end -}}
vault.hashicorp.com/agent-inject-secret-issues-kafka: secrets/data/kafka/apps/issues
vault.hashicorp.com/agent-inject-template-issues-kafka: |-
{{- with secret "secrets/data/kafka/apps/issues" -}}
KAFKA_USERNAME={{ index .Data.data "username" }}
KAFKA_PASSWORD={{ index .Data.data "password" }}
{{- end -}}

View File

@ -3,14 +3,6 @@ kind: Kustomization
resources:
- ../base
patches:
- path: backend-s3.yaml
target:
kind: HelmRelease
name: backend
- path: celery-s3.yaml
target:
kind: HelmRelease
name: celery
- path: backend.yaml
target:
kind: HelmRelease

View File

@ -96,7 +96,11 @@ spec:
- name: SAREX_API
value:
_default: "https://sarex.contour.infra.sarex.tech"
_default: "http://backend-svc.django.svc.cluster.local:80"
- name: SAREX_HOST
value:
_default: "https://sarex.vadroad.ru"
- name: DOCUMENTATIONS_URL
value:

View File

@ -96,7 +96,11 @@ spec:
- name: SAREX_API
value:
_default: "https://srx.wb.ru"
_default: "http://backend-svc.django.svc.cluster.local:80"
- name: SAREX_HOST
value:
_default: "https://sarex.vadroad.ru"
- name: DOCUMENTATIONS_URL
value:

View File

@ -12,7 +12,6 @@ data:
# DEBUG SETTINGS START
# -----------------------------------------------------------------------------
DEBUG = True
# -----------------------------------------------------------------------------
TEST_MODE = False
@ -40,7 +39,7 @@ data:
# DEBUG SETTINGS START
# -----------------------------------------------------------------------------
DEBUG = True
DEBUG = False
# -----------------------------------------------------------------------------
REVIEW_HOST='http://backend-service.flows.svc.cluster.local:8000'

View File

@ -13,3 +13,28 @@ spec:
requests:
cpu: null
memory: null
envs:
- name: DOCUMENTATION_HOST
value:
_default: "http://backend-api-svc.documentations.svc.cluster.local/api/v1"
- name: FLOW_HOST
value:
_default: "http://backend-svc.flows.svc.cluster.local/api/v1"
- name: DJANGO_HOST
value:
_default: "http://backend-svc.django.svc.cluster.local/api"
- name: NOTE_HOST
value:
_default: "http://backend-service.notes.svc.cluster.local:8000/api/v1"
- name: REDIS_USE
value:
_default: "0"
- name: TIMEOUT
value:
_default: "120"

View File

@ -66,7 +66,7 @@ spec:
enabled: false
image:
name:
_default: cr.yandex/crp3ccidau046kdj8g9q/notes-backend:production_81366854
_default: cr.yandex/crp3ccidau046kdj8g9q/notes-backend:preprod_c00faf6e
pullPolicy:
_default: IfNotPresent
service:

View File

@ -13,3 +13,52 @@ spec:
requests:
cpu: null
memory: null
envs:
- name: PG_SSL_MODE
value:
_default: "disable"
- name: DJANGO_HOST
value:
_default: "http://backend-svc.django.svc.cluster.local"
- name: BASE_HOST
value:
_default: "https://sarex.local.uralkali.com/notes"
- name: TIMEOUT
value:
_default: "120"
- name: FAAS_SERVICE
value:
_default: "https://api.sarex.io/lambdas"
- name: WORKSPACE_URL
value:
_default: "http://backend-svc.workspaces.svc.cluster.local/api/v1"
- name: WORKFLOW_HOST
value:
_default: "http://backend-svc.processing.svc.cluster.local/api/v1"
- name: WORKFLOW_TAG
value:
_default: "stable"
- name: RESOURCE_URL
value:
_default: "https://api.sarex.io/resources/api/v1"
- name: SYNC_RESOURCE_ID
value:
_default: "0"
- name: ENABLE_ND
value:
_default: "0"
- name: ATTACHMENT_HOST
value:
_default: "http://attachments-service.attachments.svc.cluster.local:8000/api/v1"

View File

@ -147,6 +147,28 @@ spec:
value:
_default: "/api/v1"
- name: KAFKA_ENABLE
value:
_default: "True"
- name: KAFKA_BOOTSTRAP_SERVERS
value:
_default: '["wb-prod-kafka-bootstrap.kafka.svc.cluster.local:9093"]'
- name: KAFKA_SECURITY_PROTOCOL
value:
_default: "SSL"
- name: KAFKA_SSL_CAFILE
value:
_default: "/usr/local/share/ca-certificates/kafka.crt"
# Обязан совпадать с SETTINGS_TOPICS["planning"] в
# apps/message-hub/wb/message-hub.yaml
- name: KAFKA_TOPICS
value:
_default: '{"planning": "message-hub-prod"}'
commitSha: ""
gitlabUri: ""
gitlabJobUrl: ""

View File

@ -141,6 +141,26 @@ spec:
value:
_default: "/api/v1"
- name: KAFKA_ENABLE
value:
_default: "True"
- name: KAFKA_BOOTSTRAP_SERVERS
value:
_default: '["wb-prod-kafka-bootstrap.kafka.svc.cluster.local:9093"]'
- name: KAFKA_SECURITY_PROTOCOL
value:
_default: "SSL"
- name: KAFKA_SSL_CAFILE
value:
_default: "/usr/local/share/ca-certificates/kafka.crt"
- name: KAFKA_TOPICS
value:
_default: '{"planning": "message-hub-prod"}'
commitSha: ""
gitlabUri: ""
gitlabJobUrl: ""

View File

@ -0,0 +1,31 @@
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: backend
namespace: premises
spec:
values:
services:
backend:
deployment:
resources:
requests:
cpu: null
memory: null
volumes:
_default:
- name: kafka-ca-cert
mountPath:
_default: /usr/local/share/ca-certificates/kafka.crt
subPath:
_default: kafka.crt
readOnly:
_default: true
configMap:
name:
_default: kafka-ca-cert
items:
- key: kafka.crt
path:
_default: kafka.crt

View File

@ -0,0 +1,27 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: kafka-ca-cert
namespace: premises
data:
kafka.crt: |
-----BEGIN CERTIFICATE-----
MIIDETCCAfmgAwIBAgIQI30u4fwgUnGBxyLicuU5EzANBgkqhkiG9w0BAQsFADAT
MREwDwYDVQQDEwhrYWZrYS1jYTAeFw0yNjA3MTMxNzQwNDJaFw0yNzA3MTMxNzQw
NDJaMBMxETAPBgNVBAMTCGthZmthLWNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAudTWG0AwdqIMqbqGwjf9CY0BMMQm+HDPRkzMnXqVCSqAYLBLuPBC
h4+qm+IKAIpiJrO5pCDxeU1mVqMgRnXcdYyuefCzlTAKMNuM1CVM4ou695B0zKiy
D+7NHsdhuoH/ne3jCa8VpylDfKWsxcq3tDCdtZ5drPK80g2o0eo2LHx4erJtSABV
tqCrcIuy1nClAwGY4ejO+psr+gIzrHdYzve6YRRFBqVp6sJHcW1Cj6wOpHax4pcM
Srh5EcZ4dk434UNOZy2Ebji/9Lwxn0CiXtPTHYGTgNLhujurylFM1nUx69QgsR3C
GRZSY3R8Kegd4bzzhHfoBMQvl5Py+0o85QIDAQABo2EwXzAOBgNVHQ8BAf8EBAMC
AqQwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA8GA1UdEwEB/wQFMAMB
Af8wHQYDVR0OBBYEFKhTGCqho/YjUZK1ndypuYs970kcMA0GCSqGSIb3DQEBCwUA
A4IBAQBvIzVhkzib6LJxt3tUkDFy87Yf1gG+rRVZiL/ZGrOsQlvBt4eLzZIytAvL
QaZHY+imIyzURj57IFfyFM1fEPRhc9et0VaRYxGwapLljez0jqPedM8rCsunJmVP
KrQxAfvbmHvcZ8k51tpD+YydmoARjBmoRdRIuLTDsuLv0Szg45M/7I4px2ycGN2j
kF7jVwF56u2eIrUGybnsH2qg+MY7devv3rG1Y1YV7HEwMAAeN1n5JLxxuA1AIW/j
TyZD8hICp8OLzWGTG9b3GZJK9FXbDHSKXemJr0hyjoxsW27nHsXcmV5Oe2OkTKw8
fdA17/ibw6gFrH2b3vZKcx8D455V
-----END CERTIFICATE-----

View File

@ -0,0 +1,14 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
- kafka-ca-configmap.yaml
patches:
- path: namespace.yaml
target:
kind: Namespace
name: premises
- path: backend.yaml
target:
kind: HelmRelease
name: backend

View File

@ -0,0 +1,8 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: premises
labels:
istio-injection: enabled
security.deckhouse.io/pod-policy: privileged

View File

@ -42,7 +42,7 @@ spec:
image:
name:
_default: cr.yandex/crp3ccidau046kdj8g9q/workflows-engine:contour_a03d37da-dirty2
_default: cr.yandex/crp3ccidau046kdj8g9q/workflows-engine:contour_835b57c1
pullPolicy:
_default: IfNotPresent
@ -111,6 +111,10 @@ spec:
- name: POSTGRES_POOL_SIZE
value:
_default: "20"
- name: COMPARISONS_API_DB
value:
_default: "/etc/comparisons/comparisons-db-prod.json"
- name: ENVIRONMENT
value:
@ -127,6 +131,20 @@ spec:
- name: API_ADDRESS
value:
_default: "0.0.0.0:8000"
- name: ENABLE_CROSS_SECTION_API_DB
value:
_default: "1"
- name: CROSS_SECTION_API_DB
value:
_default: "/etc/cross_section/cross-section-api-db-prod.json"
- name: CROSS_SECTION_API_DEBUG
value:
_default: "0"
- name: IGNORE_RESOURCES
value:
_default: "True"
- name: DJANGO_HOST
value:

View File

@ -8,6 +8,9 @@ spec:
values:
services:
backend:
image:
name:
_default: cr.yandex/crp3ccidau046kdj8g9q/workflows-engine:contour_7d2cd329
deployment:
resources:
requests:

View File

@ -35,7 +35,7 @@ spec:
image:
name:
_default: cr.yandex/crp3ccidau046kdj8g9q/remarks-frontend:wb_002f8896
_default: cr.yandex/crp3ccidau046kdj8g9q/remarks-frontend:contour_013c5091
pullPolicy:
_default: IfNotPresent

View File

@ -29,7 +29,7 @@ spec:
enabled: true
image:
name:
_default: cr.yandex/crp3ccidau046kdj8g9q/workspaces-v2-frontend:contour_a72e3265
_default: cr.yandex/crp3ccidau046kdj8g9q/workspaces-v2-frontend:contour_2da2a00e
pullPolicy:
_default: IfNotPresent
deployment:

View File

@ -8,6 +8,9 @@ spec:
values:
services:
frontend:
image:
name:
_default: cr.yandex/crp3ccidau046kdj8g9q/workspaces-v2-frontend:contour_1b5d64e4
deployment:
replicaCount:
_default: 1

View File

@ -36,7 +36,7 @@ spec:
image:
name:
_default: 10.4.10.187:80/library/workspaces-v2-frontend:contour_07373a45
_default: 10.4.10.187:80/library/workspaces-v2-frontend:contour_1b5d64e4
pullPolicy:
_default: IfNotPresent

163
ci/build-slice.py Normal file
View File

@ -0,0 +1,163 @@
#!/usr/bin/env python3
import argparse
import io
import subprocess
import sys
import tarfile
from pathlib import Path, PurePosixPath
import yaml
FLUX_KUSTOMIZATION = "kustomize.toolkit.fluxcd.io"
KUSTOMIZATION_FILES = ("kustomization.yaml", "kustomization.yml", "Kustomization")
class SliceError(Exception):
pass
def is_remote(ref: str) -> bool:
return "://" in ref or ref.startswith(("git@", "github.com/", "gitlab.com/"))
def kustomization_file(directory: Path) -> Path | None:
for name in KUSTOMIZATION_FILES:
candidate = directory / name
if candidate.is_file():
return candidate
return None
def local_refs(doc: dict) -> list[str]:
refs = []
refs += doc.get("resources") or []
refs += doc.get("components") or []
refs += doc.get("patchesStrategicMerge") or []
refs += [p["path"] for p in doc.get("patches") or [] if isinstance(p, dict) and "path" in p]
for key in ("configMapGenerator", "secretGenerator"):
for gen in doc.get(key) or []:
for entry in (gen.get("files") or []) + (gen.get("envs") or []):
refs.append(entry.split("=", 1)[-1])
if gen.get("env"):
refs.append(gen["env"])
return [r for r in refs if isinstance(r, str)]
def flux_paths(path: Path) -> list[str]:
try:
docs = list(yaml.safe_load_all(path.read_text()))
except yaml.YAMLError:
return []
return [
d["spec"]["path"]
for d in docs
if isinstance(d, dict)
and str(d.get("apiVersion", "")).startswith(FLUX_KUSTOMIZATION)
and d.get("kind") == "Kustomization"
and d.get("spec", {}).get("path")
]
def collect(repo: Path, start: str) -> tuple[set[PurePosixPath], list[str]]:
repo = repo.resolve()
files: set[PurePosixPath] = set()
entries: list[str] = []
seen_dirs: set[Path] = set()
def rel(p: Path) -> PurePosixPath:
try:
return PurePosixPath(p.resolve().relative_to(repo).as_posix())
except ValueError:
raise SliceError(f"reference outside the repository: {p}")
def add_file(p: Path):
r = rel(p)
if r in files:
return
files.add(r)
if p.suffix in (".yaml", ".yml"):
for fp in flux_paths(p):
visit_dir(repo / fp, entry=True)
def visit_dir(d: Path, entry: bool = False):
d = d.resolve()
if d in seen_dirs:
return
seen_dirs.add(d)
kfile = kustomization_file(d)
if kfile is None:
raise SliceError(f"no kustomization.yaml in {rel(d)}")
if entry:
entries.append(str(rel(d)))
add_file(kfile)
doc = yaml.safe_load(kfile.read_text()) or {}
for ref in local_refs(doc):
if is_remote(ref):
raise SliceError(f"remote reference {ref} in {rel(kfile)}")
target = (d / ref)
if target.is_dir():
visit_dir(target)
elif target.is_file():
add_file(target)
else:
raise SliceError(f"reference {ref} in {rel(kfile)} does not exist")
visit_dir(repo / start, entry=True)
return files, sorted(set(entries))
def write_tar(repo: Path, files: set[PurePosixPath], out: Path):
buf = io.BytesIO()
with tarfile.open(fileobj=buf, mode="w", format=tarfile.PAX_FORMAT) as tar:
for f in sorted(files):
data = (repo / f).read_bytes()
info = tarfile.TarInfo(str(f))
info.size = len(data)
info.mode = 0o644
info.mtime = 0
info.uid = info.gid = 0
info.uname = info.gname = ""
tar.addfile(info, io.BytesIO(data))
out.write_bytes(buf.getvalue())
def kustomize_build(path: Path) -> bytes:
p = subprocess.run(["kubectl", "kustomize", str(path)], capture_output=True)
if p.returncode != 0:
raise SliceError(f"kustomize build {path} failed: {p.stderr.decode().strip()}")
return p.stdout
def verify(repo: Path, out: Path, entries: list[str]):
import tempfile
with tempfile.TemporaryDirectory() as tmp:
with tarfile.open(out) as tar:
tar.extractall(tmp, filter="data")
for e in entries:
if kustomize_build(repo / e) != kustomize_build(Path(tmp) / e):
raise SliceError(f"kustomize build of {e} differs between slice and full repository")
def main() -> int:
ap = argparse.ArgumentParser()
ap.add_argument("contour")
ap.add_argument("--repo", default=".")
ap.add_argument("--out", required=True)
ap.add_argument("--no-verify", action="store_true")
args = ap.parse_args()
repo = Path(args.repo).resolve()
out = Path(args.out)
try:
files, entries = collect(repo, f"clusters/{args.contour}")
write_tar(repo, files, out)
if not args.no_verify:
verify(repo, out, entries)
except SliceError as e:
print(f"slice {args.contour}: {e}", file=sys.stderr)
return 1
print(f"slice {args.contour}: {len(files)} files, entry points: {', '.join(entries)}")
return 0
if __name__ == "__main__":
sys.exit(main())

217
ci/publish-slice.py Normal file
View File

@ -0,0 +1,217 @@
#!/usr/bin/env python3
import argparse
import base64
import hashlib
import importlib.util
import json
import re
import sys
import tempfile
import time
import urllib.error
import urllib.parse
import urllib.request
from datetime import datetime, timezone
from pathlib import Path
import yaml
spec = importlib.util.spec_from_file_location("build_slice", Path(__file__).with_name("build-slice.py"))
bs = importlib.util.module_from_spec(spec)
spec.loader.exec_module(bs)
REGISTRY_HOST = "cr.yandex"
SLICE_REGISTRY = "crpct2b2lsmao4nm0cjk"
CONFIG_TYPE = "application/vnd.sarex.slice.config.v1+json"
LAYER_TYPE = "application/vnd.oci.image.layer.v1.tar"
MANIFEST_TYPE = "application/vnd.oci.image.manifest.v1+json"
JOB_IMAGE = "${CR}/infra/slice-builder:1.0.0"
class PublishError(Exception):
pass
def digest(data: bytes) -> str:
return "sha256:" + hashlib.sha256(data).hexdigest()
def list_contours(repo: Path) -> list[str]:
return sorted(p.parent.name for p in repo.glob("clusters/*/kustomization.yaml"))
def child_pipeline(contours: list[str], release: str, commit: str) -> str:
jobs: dict = {"stages": ["slices"]}
for c in contours:
jobs[f"slice {c}"] = {
"stage": "slices",
"image": JOB_IMAGE,
"tags": ["build"],
"allow_failure": True,
"variables": {"GIT_DEPTH": "1"},
"script": [
"printf '%s' \"$SLICES_PUSHER_KEY\" | base64 -d > /tmp/slices-key.json",
f"python3 ci/publish-slice.py publish --contour {c} --release {release} --commit {commit} --key-file /tmp/slices-key.json",
],
"after_script": ["rm -f /tmp/slices-key.json"],
}
if not contours:
jobs["no contours"] = {"stage": "slices", "image": JOB_IMAGE, "tags": ["build"], "script": ["echo 'no clusters/*/kustomization.yaml found'"]}
return yaml.safe_dump(jobs, sort_keys=False, allow_unicode=False)
def build_manifest(layer: bytes, annotations: dict[str, str]) -> tuple[bytes, bytes]:
config = b"{}"
manifest = {
"schemaVersion": 2,
"mediaType": MANIFEST_TYPE,
"config": {"mediaType": CONFIG_TYPE, "digest": digest(config), "size": len(config)},
"layers": [{
"mediaType": LAYER_TYPE,
"digest": digest(layer),
"size": len(layer),
"annotations": {"org.opencontainers.image.title": "slice.tar"},
}],
"annotations": dict(sorted(annotations.items())),
}
return config, json.dumps(manifest, sort_keys=True, separators=(",", ":")).encode()
class Registry:
def __init__(self, username: str, password: str):
self.base = f"https://{REGISTRY_HOST}"
self.basic = "Basic " + base64.b64encode(f"{username}:{password}".encode()).decode()
self.tokens: dict[str, str] = {}
def _send(self, method, url, data=None, headers=None):
req = urllib.request.Request(url, data=data, method=method, headers=headers or {})
try:
with urllib.request.urlopen(req, timeout=60) as r:
return r.status, dict(r.headers), r.read()
except urllib.error.HTTPError as e:
return e.code, dict(e.headers), e.read()
def _token(self, challenge: str, scope: str) -> str:
params = dict(re.findall(r'(\w+)="([^"]*)"', challenge))
realm = params.pop("realm")
params["scope"] = scope
status, _, body = self._send("GET", f"{realm}?{urllib.parse.urlencode(params)}", headers={"Authorization": self.basic})
if status != 200:
raise PublishError(f"registry auth failed: HTTP {status}")
payload = json.loads(body)
return payload.get("token") or payload.get("access_token")
def request(self, method, repo, path, data=None, headers=None):
scope = f"repository:{repo}:pull,push"
url = path if path.startswith("http") else f"{self.base}/v2/{repo}/{path}"
headers = dict(headers or {})
if scope in self.tokens:
headers["Authorization"] = f"Bearer {self.tokens[scope]}"
status, h, body = self._send(method, url, data, headers)
if status == 401:
challenge = {k.lower(): v for k, v in h.items()}.get("www-authenticate", "")
self.tokens[scope] = self._token(challenge, scope)
headers["Authorization"] = f"Bearer {self.tokens[scope]}"
status, h, body = self._send(method, url, data, headers)
return status, {k.lower(): v for k, v in h.items()}, body
def current_layer(self, repo: str) -> str | None:
status, _, body = self.request("GET", repo, "manifests/current", headers={"Accept": MANIFEST_TYPE})
if status == 404:
return None
if status != 200:
raise PublishError(f"{repo}:current: HTTP {status}")
return json.loads(body)["layers"][0]["digest"]
def put_blob(self, repo: str, data: bytes) -> bool:
d = digest(data)
if self.request("HEAD", repo, f"blobs/{d}")[0] == 200:
return False
status, h, _ = self.request("POST", repo, "blobs/uploads/")
if status != 202:
raise PublishError(f"blob upload to {repo}: HTTP {status}")
location = h["location"]
if location.startswith("/"):
location = self.base + location
sep = "&" if "?" in location else "?"
status, _, _ = self.request("PUT", repo, f"{location}{sep}digest={d}", data, {"Content-Type": "application/octet-stream"})
if status != 201:
raise PublishError(f"blob upload to {repo}: HTTP {status}")
return True
def push(self, repo: str, tags: list[str], layer: bytes, annotations: dict[str, str]) -> bool:
config, manifest = build_manifest(layer, annotations)
self.put_blob(repo, config)
uploaded = self.put_blob(repo, layer)
for tag in tags:
status, _, body = self.request("PUT", repo, f"manifests/{tag}", manifest, {"Content-Type": MANIFEST_TYPE})
if status != 201:
raise PublishError(f"{repo}:{tag}: HTTP {status} {body[:200]!r}")
return uploaded
def log(msg: str):
print(f"[{time.strftime('%H:%M:%S')}] {msg}", flush=True)
def publish(repo: Path, contour: str, release: str, commit: str, key_file: Path) -> int:
target = f"{SLICE_REGISTRY}/{contour}-iac"
log(f"contour {contour}, source iac@{commit[:8]}, release {release}")
try:
with tempfile.TemporaryDirectory() as tmp:
out = Path(tmp) / "slice.tar"
files, entries = bs.collect(repo, f"clusters/{contour}")
log(f"collected {len(files)} files, entry points: {', '.join(entries)}")
bs.write_tar(repo, files, out)
bs.verify(repo, out, entries)
log(f"verified: kustomize build of {len(entries)} entry point(s) identical to full repository")
layer = out.read_bytes()
new = digest(layer)
log(f"slice size {len(layer)} bytes, digest {new}")
registry = Registry("json_key", key_file.read_text())
current = registry.current_layer(f"{target}")
changed = current != new
log(f"registry {REGISTRY_HOST}/{target}, current " + (current or "absent") + (", content changed" if changed else ", content unchanged"))
tags = [commit[:8], release] + (["current"] if changed else [])
uploaded = registry.push(target, tags, layer, {
"org.opencontainers.image.source": "iac",
"org.opencontainers.image.revision": commit,
"org.opencontainers.image.version": release,
"org.opencontainers.image.created": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
"io.sarex.slice.contour": contour,
"io.sarex.slice.kind": "iac",
})
log(f"layer {'uploaded' if uploaded else 'already in registry'}, tags pushed: {', '.join(tags)}")
except (bs.SliceError, PublishError) as e:
log(f"FAILED: {e}")
return 1
log("done")
return 0
def main() -> int:
ap = argparse.ArgumentParser()
sub = ap.add_subparsers(dest="cmd", required=True)
gen = sub.add_parser("generate")
gen.add_argument("--repo", default=".")
gen.add_argument("--release", required=True)
gen.add_argument("--commit", required=True)
gen.add_argument("--out", required=True)
pub = sub.add_parser("publish")
pub.add_argument("--repo", default=".")
pub.add_argument("--contour", required=True)
pub.add_argument("--release", required=True)
pub.add_argument("--commit", required=True)
pub.add_argument("--key-file", required=True)
args = ap.parse_args()
repo = Path(args.repo).resolve()
if args.cmd == "generate":
contours = list_contours(repo)
Path(args.out).write_text(child_pipeline(contours, args.release, args.commit))
log(f"{len(contours)} contours: {', '.join(contours)}")
return 0
return publish(repo, args.contour, args.release, args.commit, Path(args.key_file))
if __name__ == "__main__":
sys.exit(main())

View File

@ -0,0 +1,93 @@
import importlib.util
import tarfile
from pathlib import Path
import pytest
import yaml
spec = importlib.util.spec_from_file_location("build_slice", Path(__file__).parents[1] / "build-slice.py")
bs = importlib.util.module_from_spec(spec)
spec.loader.exec_module(bs)
def put(root: Path, rel: str, text: str):
p = root / rel
p.parent.mkdir(parents=True, exist_ok=True)
p.write_text(text)
@pytest.fixture
def repo(tmp_path):
put(tmp_path, "clusters/a/kustomization.yaml", "resources:\n - ./flux-system\n - ./layers.yaml\n")
put(tmp_path, "clusters/a/flux-system/kustomization.yaml", "resources:\n - gotk-sync.yaml\n")
put(tmp_path, "clusters/a/flux-system/gotk-sync.yaml",
"apiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nspec:\n path: ./clusters/a\n")
put(tmp_path, "clusters/a/layers.yaml",
"apiVersion: kustomize.toolkit.fluxcd.io/v1\nkind: Kustomization\nspec:\n path: ./layers/a/00-vault\n")
put(tmp_path, "layers/a/00-vault/kustomization.yaml", "resources:\n - ../../../infrastructure/vault/contour-template\n")
put(tmp_path, "infrastructure/vault/contour-template/kustomization.yaml",
"resources:\n - ../base\npatches:\n - path: vault.yaml\n")
put(tmp_path, "infrastructure/vault/contour-template/vault.yaml", "kind: HelmRelease\n")
put(tmp_path, "infrastructure/vault/base/kustomization.yaml", "resources:\n - helmrelease.yaml\n")
put(tmp_path, "infrastructure/vault/base/helmrelease.yaml", "kind: HelmRelease\n")
put(tmp_path, "infrastructure/vault/base/unused.yaml", "kind: ConfigMap\n")
put(tmp_path, "infrastructure/vault/uralkal/kustomization.yaml", "resources:\n - ../base\n")
put(tmp_path, "clusters/b/kustomization.yaml", "resources:\n - ../../infrastructure/vault/uralkal\n")
return tmp_path
def test_slice_follows_flux_paths_and_skips_foreign(repo):
files, entries = bs.collect(repo, "clusters/a")
names = {str(f) for f in files}
assert "infrastructure/vault/base/helmrelease.yaml" in names
assert "infrastructure/vault/contour-template/vault.yaml" in names
assert "layers/a/00-vault/kustomization.yaml" in names
assert not any("uralkal" in n or n.startswith("clusters/b") for n in names)
assert "infrastructure/vault/base/unused.yaml" not in names
assert entries == ["clusters/a", "layers/a/00-vault"]
def test_remote_reference_stops_build(repo):
put(repo, "clusters/a/kustomization.yaml", "resources:\n - https://github.com/x/y//z\n")
with pytest.raises(bs.SliceError, match="remote reference"):
bs.collect(repo, "clusters/a")
def test_dangling_reference_stops_build(repo):
put(repo, "clusters/a/kustomization.yaml", "resources:\n - ./missing.yaml\n")
with pytest.raises(bs.SliceError, match="does not exist"):
bs.collect(repo, "clusters/a")
def test_tar_is_byte_identical_across_runs(repo, tmp_path_factory):
files, _ = bs.collect(repo, "clusters/a")
out1 = tmp_path_factory.mktemp("o") / "s.tar"
out2 = tmp_path_factory.mktemp("o") / "s.tar"
bs.write_tar(repo, files, out1)
(repo / "clusters/a/layers.yaml").touch()
bs.write_tar(repo, files, out2)
assert out1.read_bytes() == out2.read_bytes()
with tarfile.open(out1) as t:
assert all(m.mtime == 0 for m in t.getmembers())
pspec = importlib.util.spec_from_file_location("publish_slice", Path(__file__).parents[1] / "publish-slice.py")
ps = importlib.util.module_from_spec(pspec)
pspec.loader.exec_module(ps)
def test_every_cluster_with_kustomization_is_a_contour(tmp_path):
put(tmp_path, "clusters/stand/kustomization.yaml", "resources: []\n")
put(tmp_path, "clusters/vad/kustomization.yaml", "resources: []\n")
put(tmp_path, "clusters/contour/apps.yaml", "kind: Kustomization\n")
assert ps.list_contours(tmp_path) == ["stand", "vad"]
def test_child_pipeline_has_one_job_per_contour():
doc = yaml.safe_load(ps.child_pipeline(["stand", "vad"], "3.9.68", "abcdef1234"))
jobs = {k: v for k, v in doc.items() if k != "stages"}
assert sorted(jobs) == ["slice stand", "slice vad"]
assert all(j["allow_failure"] for j in jobs.values())
assert "--contour vad --release 3.9.68 --commit abcdef1234" in jobs["slice vad"]["script"][1]
assert all(ord(ch) < 128 for ch in ps.child_pipeline(["stand"], "1.0.0", "a" * 40))

View File

@ -47,6 +47,7 @@ resources:
- ../../apps/document-link/d8-ugmk-prod
- ../../apps/bim/d8-ugmk-prod
- ../../apps/cde/d8-ugmk-prod
- ../../apps/premises/d8-ugmk-prod
- ../../apps/flows/d8-ugmk-prod
- ../../apps/inspections/d8-ugmk-prod
- ../../apps/issues/d8-ugmk-prod

View File

@ -0,0 +1,14 @@
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: yc-oci-charts
namespace: flux-system
spec:
type: oci
interval: 10m0s
url: ${CHART_REPO:=oci://cr.yandex/crp3ccidau046kdj8g9q/charts}
secretRef:
name: ${CHART_REPO_SECRET:=yc-cr-auth}
certSecretRef:
name: chart-repo-ca

View File

@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./helm-repositories.yaml
- ../../../infrastructure/vault/contour-template

View File

@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../../infrastructure/istio-base/contour-template
- ../../../infrastructure/istio-pilot/contour-template
- ../../../infrastructure/istio-gateway/contour-template
- ../../../infrastructure/cert-manager/contour-template

View File

@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../../infrastructure/postgresql/contour-template
- ../../../infrastructure/kafka/contour-template
- ../../../infrastructure/rabbitmq/contour-template

View File

@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../../infrastructure/zitadel/contour-template
- ../../../infrastructure/camunda/contour-template

View File

@ -0,0 +1,4 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../../infrastructure/istio-config/contour-template

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: flux-system
namespace: flux-system
spec:
interval: 1m0s
ref:
branch: main
url: http://gitea.gitea.svc:3000/infra/iac.git
secretRef:
name: flux-system
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: flux-system
namespace: flux-system
spec:
interval: 10m0s
path: ./clusters/stand
prune: true
sourceRef:
kind: GitRepository
name: flux-system

View File

@ -0,0 +1,13 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- gotk-components.yaml
- gotk-sync.yaml
patches:
- target:
kind: Deployment
name: kustomize-controller
patch: |-
- op: add
path: /spec/template/spec/containers/0/args/-
value: --feature-gates=CancelHealthCheckOnNewRevision=true

View File

@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./flux-system
- ./layers.yaml

View File

@ -0,0 +1,93 @@
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: 00-vault
namespace: flux-system
spec:
interval: 10m0s
timeout: 10m0s
path: ./clusters/stand/00-vault
prune: true
sourceRef:
kind: GitRepository
name: flux-system
postBuild:
substituteFrom:
- kind: ConfigMap
name: contour-vars
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: 10-mesh
namespace: flux-system
spec:
interval: 10m0s
timeout: 15m0s
path: ./clusters/stand/10-mesh
prune: true
wait: true
sourceRef:
kind: GitRepository
name: flux-system
postBuild:
substituteFrom:
- kind: ConfigMap
name: contour-vars
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: 20-data
namespace: flux-system
spec:
interval: 10m0s
timeout: 20m0s
path: ./clusters/stand/20-data
prune: true
wait: true
sourceRef:
kind: GitRepository
name: flux-system
postBuild:
substituteFrom:
- kind: ConfigMap
name: contour-vars
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: 30-platform
namespace: flux-system
spec:
interval: 10m0s
timeout: 35m0s
path: ./clusters/stand/30-platform
prune: true
wait: true
sourceRef:
kind: GitRepository
name: flux-system
postBuild:
substituteFrom:
- kind: ConfigMap
name: contour-vars
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: 40-routing
namespace: flux-system
spec:
interval: 10m0s
timeout: 10m0s
path: ./clusters/stand/40-routing
prune: true
wait: true
sourceRef:
kind: GitRepository
name: flux-system
postBuild:
substituteFrom:
- kind: ConfigMap
name: contour-vars

View File

@ -12,3 +12,4 @@ resources:
- ../../../infrastructure/kb/vk-infra
- ../../../infrastructure/gitlab-runner/vk-infra
- ../../../infrastructure/nexus/vk-infra
- ../../../infrastructure/outline/vk-infra

View File

@ -12,3 +12,4 @@ resources:
- ../../../infrastructure/valkey/vk-prod
- ../../../infrastructure/clickhouse/vk-prod
- ../../../infrastructure/camunda/vk-prod
- ../../../infrastructure/spicedb/vk-prod

View File

@ -137,6 +137,25 @@ spec:
prefix: /
service: goalert.goalert.svc.cluster.local
port: 8081
# Без этого VS /bimv2/api/* попадает в catch-all "/" фронта
# (django/vs-sarex-frontend) и отдаёт 200 с HTML вместо JSON.
bim-backend-v2:
namespace: bim
hosts:
- srx.wb.ru
- lk.srx.wb.ru
gateways:
- istio-system/main-gateway
cors:
allowOrigins:
- exact: https://srx.wb.ru
- exact: https://lk.srx.wb.ru
routes:
- path:
prefix: /bimv2/api/
rewrite: /api/
service: backend-service.bim.svc.cluster.local
port: 8000
vault-vs:
namespace: vault
hosts:

View File

@ -0,0 +1,354 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: camunda
namespace: camunda
spec:
dependsOn: []
interval: 5m
timeout: 30m
waitStrategy:
name: legacy
postRenderers:
- kustomize:
patches:
- target:
group: apps
version: v1
kind: Deployment
patch: |-
- op: add
path: /spec/template/spec/nodeSelector
value:
dedicated: processing
- op: add
path: /spec/template/spec/tolerations
value:
- key: dedicated
operator: Equal
value: processing
effect: NoSchedule
- target:
group: apps
version: v1
kind: StatefulSet
patch: |-
- op: add
path: /spec/template/spec/nodeSelector
value:
dedicated: processing
- op: add
path: /spec/template/spec/tolerations
value:
- key: dedicated
operator: Equal
value: processing
effect: NoSchedule
- target:
group: batch
version: v1
kind: Job
patch: |-
- op: add
path: /spec/template/spec/nodeSelector
value:
dedicated: processing
- op: add
path: /spec/template/spec/tolerations
value:
- key: dedicated
operator: Equal
value: processing
effect: NoSchedule
- target:
group: apps
version: v1
kind: Deployment
name: camunda-connectors
patch: |-
- op: add
path: /spec/template/spec/nodeSelector
value:
dedicated: processing
- op: add
path: /spec/template/spec/tolerations
value:
- key: dedicated
operator: Equal
value: processing
effect: NoSchedule
- target:
group: apps
version: v1
kind: Deployment
name: camunda-identity
patch: |-
- op: add
path: /spec/template/spec/nodeSelector
value:
dedicated: processing
- op: add
path: /spec/template/spec/tolerations
value:
- key: dedicated
operator: Equal
value: processing
effect: NoSchedule
- target:
group: apps
version: v1
kind: Deployment
name: camunda-operate
patch: |-
- op: add
path: /spec/template/spec/nodeSelector
value:
dedicated: processing
- op: add
path: /spec/template/spec/tolerations
value:
- key: dedicated
operator: Equal
value: processing
effect: NoSchedule
- target:
group: apps
version: v1
kind: Deployment
name: camunda-optimize
patch: |-
- op: add
path: /spec/template/spec/nodeSelector
value:
dedicated: processing
- op: add
path: /spec/template/spec/tolerations
value:
- key: dedicated
operator: Equal
value: processing
effect: NoSchedule
- target:
group: apps
version: v1
kind: Deployment
name: camunda-tasklist
patch: |-
- op: add
path: /spec/template/spec/nodeSelector
value:
dedicated: processing
- op: add
path: /spec/template/spec/tolerations
value:
- key: dedicated
operator: Equal
value: processing
effect: NoSchedule
- target:
group: apps
version: v1
kind: Deployment
name: camunda-zeebe-gateway
patch: |-
- op: add
path: /spec/template/spec/nodeSelector
value:
dedicated: processing
- op: add
path: /spec/template/spec/tolerations
value:
- key: dedicated
operator: Equal
value: processing
effect: NoSchedule
- target:
group: apps
version: v1
kind: StatefulSet
name: camunda-zeebe
patch: |-
- op: add
path: /spec/template/spec/nodeSelector
value:
dedicated: processing
- op: add
path: /spec/template/spec/tolerations
value:
- key: dedicated
operator: Equal
value: processing
effect: NoSchedule
values:
global:
vault:
enabled: true
role: camunda-contour
authPath: auth/kubernetes
secrets:
postgresql:
path: secrets/data/camunda/identity-db
keys:
password: password
postgresPassword: password
image:
pullSecrets:
- name: regcred
identity:
auth:
publicIssuerUrl: "https://${HOST_CAMUNDA_KEYCLOAK}/auth/realms/camunda-platform"
identity:
redirectUrl: "https://${HOST_CAMUNDA_IDENTITY}"
operate:
redirectUrl: "https://${HOST_CAMUNDA}"
tasklist:
redirectUrl: "https://${HOST_CAMUNDA_TASKLIST}"
optimize:
redirectUrl: "https://${HOST_CAMUNDA_OPTIMIZE}"
identityPostgresql:
enabled: false
auth:
usePasswordFiles: true
primary:
automountServiceAccountToken: true
persistence:
size: 10Gi
storageClass: ${STORAGE_CLASS}
identityKeycloak:
externalDatabase:
host: pg-host.storage.svc.cluster.local
port: 5432
user: bn_keycloak
database: bitnami_keycloak
password: ""
existingSecret: ""
existingSecretPasswordKey: password
postgresql:
enabled: false
auth:
usePasswordFiles: true
primary:
automountServiceAccountToken: true
persistence:
size: 10Gi
storageClass: ${STORAGE_CLASS}
vaultEnv:
enabled: true
role: camunda-contour
authPath: auth/kubernetes
envFiles:
KEYCLOAK_ADMIN_PASSWORD:
path: secrets/data/camunda/keycloak-admin
key: admin-password
KEYCLOAK_PASSWORD:
path: secrets/data/camunda/keycloak-admin
key: admin-password
KEYCLOAK_DATABASE_PASSWORD:
path: secrets/data/camunda/keycloak-db
key: password
global:
storageClass: ${STORAGE_CLASS}
tolerations: []
elasticsearch:
sysctlImage:
registry: cr.yandex
repository: crp3ccidau046kdj8g9q/contour/camunda/os-shell
tag: 12-debian-12-r32
pullSecrets:
- regcred
master:
replicaCount: 1
podAntiAffinityPreset: soft
persistence:
size: 10Gi
storageClass: ${STORAGE_CLASS}
tolerations: []
metrics:
enabled: false
serviceMonitor:
enabled: false
prometheusRule:
enabled: false
tolerations: []
camundaCanary:
enabled: false
prometheusServiceMonitor:
enabled: false
console:
image:
pullSecrets:
- name: regcred
tolerations: []
zeebe:
clusterSize: "1"
partitionCount: "1"
replicationFactor: "1"
pvcStorageClassName: ${STORAGE_CLASS}
image:
pullSecrets:
- name: regcred
tolerations: []
zeebeGateway:
replicas: 1
image:
pullSecrets:
- name: regcred
tolerations: []
identity:
fullURL: "https://${HOST_CAMUNDA_IDENTITY}"
externalDatabase:
enabled: true
host: pg-host.storage.svc.cluster.local
port: 5432
username: identity
database: identity
password: ""
existingSecret: ""
existingSecretPasswordKey: password
image:
pullSecrets:
- name: regcred
tolerations: []
operate:
image:
pullSecrets:
- name: regcred
serviceAccount:
automountServiceAccountToken: true
tolerations: []
tasklist:
image:
pullSecrets:
- name: regcred
serviceAccount:
automountServiceAccountToken: true
tolerations: []
optimize:
image:
pullSecrets:
- name: regcred
serviceAccount:
automountServiceAccountToken: true
tolerations: []
executionIdentity:
image:
pullSecrets:
- name: regcred
tolerations: []
webModeler:
image:
pullSecrets:
- name: regcred
restapi:
tolerations: []
webapp:
tolerations: []
websockets:
tolerations: []
connectors:
image:
pullSecrets:
- name: regcred
serviceAccount:
automountServiceAccountToken: true
tolerations: []

View File

@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
patches:
- path: camunda.yaml

View File

@ -0,0 +1,25 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: cert-manager
namespace: cert-manager
spec:
interval: 5m
timeout: 10m
values:
controller:
image:
registry: cr.yandex/crp3ccidau046kdj8g9q/cert-manager
repository: cert-manager
acmesolver:
image:
registry: cr.yandex/crp3ccidau046kdj8g9q/cert-manager
repository: acmesolver
webhook:
image:
registry: cr.yandex/crp3ccidau046kdj8g9q/cert-manager
repository: cert-manager-webhook
cainjector:
image:
registry: cr.yandex/crp3ccidau046kdj8g9q/cert-manager
repository: cainjector

View File

@ -0,0 +1,28 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
patches:
- path: cert-manager.yaml
- target:
group: cert-manager.io
version: v1
kind: ClusterIssuer
name: letsencrypt-issuer
patch: |-
$patch: delete
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-issuer
- target:
group: cert-manager.io
version: v1
kind: ClusterIssuer
name: letsencrypt-issuer-istio
patch: |-
$patch: delete
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-issuer-istio

View File

@ -0,0 +1,4 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base

View File

@ -0,0 +1,117 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: istio-config
namespace: default
spec:
dependsOn: []
interval: 5m
timeout: 10m
values:
global:
env: contour
environments:
contour:
istio:
gateways:
platform:
name: platform-gateway
namespace: default
selector:
istio: ingressgateway
servers:
- hosts:
- ${HOST_LOGIN}
- ${HOST_CAMUNDA}
- ${HOST_CAMUNDA_IDENTITY}
- ${HOST_CAMUNDA_KEYCLOAK}
- ${HOST_CAMUNDA_OPTIMIZE}
- ${HOST_CAMUNDA_TASKLIST}
- ${HOST_RABBITMQ}
tls:
credentialName: istio-ingress-tls
virtualServices:
zitadel:
name: zitadel-virt-service
namespace: default
hosts:
- ${HOST_LOGIN}
gateways:
- default/platform-gateway
routes:
- path:
prefix: /
service: zitadel-idp-contour.zitadel.svc.cluster.local
port: 8080
camunda-operate:
name: camunda-operate-virt-service
namespace: default
hosts:
- ${HOST_CAMUNDA}
gateways:
- default/platform-gateway
routes:
- path:
prefix: /
service: camunda-operate.camunda.svc.cluster.local
port: 80
camunda-identity:
name: camunda-identity-virt-service
namespace: default
hosts:
- ${HOST_CAMUNDA_IDENTITY}
gateways:
- default/platform-gateway
routes:
- path:
prefix: /
service: camunda-identity.camunda.svc.cluster.local
port: 80
camunda-keycloak:
name: camunda-keycloak-virt-service
namespace: default
hosts:
- ${HOST_CAMUNDA_KEYCLOAK}
gateways:
- default/platform-gateway
routes:
- path:
prefix: /
service: camunda-keycloak.camunda.svc.cluster.local
port: 80
camunda-optimize:
name: camunda-optimize-virt-service
namespace: default
hosts:
- ${HOST_CAMUNDA_OPTIMIZE}
gateways:
- default/platform-gateway
routes:
- path:
prefix: /
service: camunda-optimize.camunda.svc.cluster.local
port: 80
camunda-tasklist:
name: camunda-tasklist-virt-service
namespace: default
hosts:
- ${HOST_CAMUNDA_TASKLIST}
gateways:
- default/platform-gateway
routes:
- path:
prefix: /
service: camunda-tasklist.camunda.svc.cluster.local
port: 80
rabbitmq:
name: rabbitmq-virt-service
namespace: default
hosts:
- ${HOST_RABBITMQ}
gateways:
- default/platform-gateway
routes:
- path:
prefix: /
service: rabbitmq.rabbitmq.svc.cluster.local
port: 15672

View File

@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
patches:
- path: istio-config.yaml

View File

@ -336,7 +336,7 @@ spec:
service: backend-svc.transmittal.svc.cluster.local
port: 80
inspections-api:
name: flows-api-virt-service
name: inspections-api-virt-service
namespace: default
hosts:
- sarex.uralmine.com
@ -348,6 +348,19 @@ spec:
rewrite: /api/
service: backend-svc.inspections.svc.cluster.local
port: 80
premises-api:
name: premises-api-virt-service
namespace: default
hosts:
- sarex.uralmine.com
gateways:
- default/platform-gateway
routes:
- path:
prefix: /premises/api/
rewrite: /api/
service: backend-svc.premises.svc.cluster.local
port: 80
reviews-frontend:
name: reviews-frontend-virt-service
namespace: default
@ -361,6 +374,19 @@ spec:
rewrite: /
service: frontend-svc.reviews.svc.cluster.local
port: 80
admin-frontend:
name: admin-frontend-virt-service
namespace: default
hosts:
- sarex.uralmine.com
gateways:
- default/platform-gateway
routes:
- path:
prefix: /admin-frontend/static/
rewrite: /
service: admin-frontend-svc.control-interface.svc.cluster.local
port: 8080
eav-api:
name: eav-api-virt-service
namespace: default

View File

@ -89,6 +89,19 @@ spec:
rewrite: /
service: frontend-svc.documentations.svc.cluster.local
port: 80
mapper-api:
name: mapper-api-virt-service
namespace: gateway
hosts:
- sarex.local.uralkali.com
gateways:
- default/platform-gateway
routes:
- path:
prefix: /mapper/api/
rewrite: /api/
service: backend-svc.mapper.svc.cluster.local
port: 80
rfi-frontend:
name: rfi-frontend-virt-service
namespace: default
@ -325,7 +338,7 @@ spec:
service: backend-svc.transmittal.svc.cluster.local
port: 80
inspections-api:
name: flows-api-virt-service
name: inspections-api-virt-service
namespace: default
hosts:
- sarex.local.uralkali.com
@ -415,6 +428,19 @@ spec:
rewrite: /
service: frontend-service.notes.svc.cluster.local
port: 80
admin-frontend:
name: admin-frontend-virt-service
namespace: default
hosts:
- sarex.local.uralkali.com
gateways:
- default/platform-gateway
routes:
- path:
prefix: /admin-frontend/static/
rewrite: /
service: admin-frontend-svc.control-interface.svc.cluster.local
port: 8080
eav-api:
name: eav-api-virt-service
namespace: default

View File

@ -323,7 +323,7 @@ spec:
service: backend-svc.transmittal.svc.cluster.local
port: 80
inspections-api:
name: flows-api-virt-service
name: inspections-api-virt-service
namespace: default
hosts:
- sarex.vadroad.ru

View File

@ -58,6 +58,18 @@ spec:
renewBefore: 360h0m0s
privateKey:
rotationPolicy: Always
srx-ui-kit-tls:
dnsNames:
- srx-ui-kit.infra.sarex.tech
- srx-ui-kit-stage.infra.sarex.tech
issuerRef:
name: letsencrypt-issuer-istio
kind: ClusterIssuer
spec:
duration: 2160h0m0s
renewBefore: 360h0m0s
privateKey:
rotationPolicy: Always
nexus-tls:
dnsNames:
- nexus.infra.sarex.tech
@ -80,6 +92,28 @@ spec:
renewBefore: 360h0m0s
privateKey:
rotationPolicy: Always
wiki-tls:
dnsNames:
- wiki.sarex.space
issuerRef:
name: letsencrypt-issuer-istio
kind: ClusterIssuer
spec:
duration: 2160h0m0s
renewBefore: 360h0m0s
privateKey:
rotationPolicy: Always
goalert-tls:
dnsNames:
- goalert.infra.sarex.io
issuerRef:
name: letsencrypt-issuer-istio
kind: ClusterIssuer
spec:
duration: 2160h0m0s
renewBefore: 360h0m0s
privateKey:
rotationPolicy: Always
istio:
gateways:
vault:
@ -104,6 +138,18 @@ spec:
tls:
credentialName: kb-tls
mode: SIMPLE
srx-ui-kit:
name: srx-ui-kit-gateway
namespace: istio-system
selector:
istio: ingressgateway
servers:
- hosts:
- srx-ui-kit.infra.sarex.tech
- srx-ui-kit-stage.infra.sarex.tech
tls:
credentialName: srx-ui-kit-tls
mode: SIMPLE
nexus:
name: nexus-gateway
namespace: istio-system
@ -126,6 +172,28 @@ spec:
tls:
credentialName: idp-tls
mode: SIMPLE
wiki:
name: wiki-gateway
namespace: istio-system
selector:
istio: ingressgateway
servers:
- hosts:
- wiki.sarex.space
tls:
credentialName: wiki-tls
mode: SIMPLE
goalert:
name: goalert-gateway
namespace: istio-system
selector:
istio: ingressgateway
servers:
- hosts:
- goalert.infra.sarex.io
tls:
credentialName: goalert-tls
mode: SIMPLE
virtualServices:
vault-virt-service:
namespace: istio-system
@ -149,6 +217,28 @@ spec:
prefix: /
service: kb-service.kb.svc.cluster.local
port: 80
srx-ui-kit-virt-service:
namespace: istio-system
hosts:
- srx-ui-kit.infra.sarex.tech
gateways:
- istio-system/srx-ui-kit-gateway
routes:
- path:
prefix: /
service: universal-static-site-srx-ui-kit-pages.gitlab-pages-srx-ui-kit.svc.cluster.local
port: 80
srx-ui-kit-stage-virt-service:
namespace: istio-system
hosts:
- srx-ui-kit-stage.infra.sarex.tech
gateways:
- istio-system/srx-ui-kit-gateway
routes:
- path:
prefix: /
service: universal-static-site-srx-ui-kit-stage-pages.gitlab-pages-srx-ui-kit-stage.svc.cluster.local
port: 80
nexus-virt-service:
namespace: istio-system
hosts:
@ -171,3 +261,25 @@ spec:
prefix: /
service: idp.zitadel.svc.cluster.local
port: 8080
wiki-virt-service:
namespace: istio-system
hosts:
- wiki.sarex.space
gateways:
- istio-system/wiki-gateway
routes:
- path:
prefix: /
service: outline.outline.svc.cluster.local
port: 80
goalert-virt-service:
namespace: istio-system
hosts:
- goalert.infra.sarex.io
gateways:
- istio-system/goalert-gateway
routes:
- path:
prefix: /
service: goalert.goalert.svc.cluster.local
port: 8081

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: ingressgateway
namespace: istio-system
spec:
interval: 5m
timeout: 10m
dependsOn:
- name: istio-base
namespace: istio-system
- name: istiod
namespace: istio-system
values:
_internal_defaults_do_not_set:
replicaCount: ${GATEWAY_REPLICAS}
service:
type: ClusterIP
nodeSelector:
sarex.io/gateway: "true"
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
istio: ingressgateway
topologyKey: kubernetes.io/hostname
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule

View File

@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
patches:
- path: istio-gateway.yaml

View File

@ -10,7 +10,7 @@ metadata:
istio: ingressgateway
spec:
type: LoadBalancer
loadBalancerIP: 161.104.106.190
loadBalancerIP: 168.113.132.114
externalTrafficPolicy: Local
selector:
app: istio-ingressgateway

View File

@ -0,0 +1,12 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: istiod
namespace: istio-system
spec:
interval: 5m
timeout: 10m
values:
global:
imagePullSecrets:
- regcred

View File

@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
patches:
- path: istio-pilot.yaml

View File

@ -0,0 +1,73 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: kafka
namespace: kafka
spec:
interval: 5m
timeout: 10m
postRenderers:
- kustomize:
patches:
- target:
group: apps
version: v1
kind: StatefulSet
namespace: kafka
patch: |-
- op: add
path: /spec/template/spec/nodeSelector
value:
dedicated: generic
- op: add
path: /spec/template/spec/tolerations
value: []
values:
global:
imagePullSecrets:
- regcred
defaultStorageClass: ${STORAGE_CLASS}
image:
pullSecrets:
- regcred
controller:
replicaCount: 1
automountServiceAccountToken: true
persistence:
size: 8Gi
storageClass: ${STORAGE_CLASS}
overrideConfiguration:
offsets.topic.replication.factor: 1
transaction.state.log.replication.factor: 1
transaction.state.log.min.isr: 1
default.replication.factor: 1
min.insync.replicas: 1
broker:
replicaCount: 0
automountServiceAccountToken: true
listeners:
client:
protocol: SASL_PLAINTEXT
sslClientAuth: "none"
provisioning:
enabled: false
sasl:
managedExistingSecret:
enabled: false
existingSecret: ""
enabledMechanisms: PLAIN,SCRAM-SHA-512
interBrokerMechanism: PLAIN
controllerMechanism: PLAIN
client:
users: []
passwords: ""
tls:
type: PEM
vault:
enabled: true
role: kafka
authPath: auth/kubernetes
secretPath: secrets/data/kafka/bootstrap
clusterIdKey: clusterId
interBrokerPasswordKey: interBrokerPassword
controllerPasswordKey: controllerPassword

View File

@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
patches:
- path: kafka.yaml

View File

@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- valkey.yaml
- outline.yaml

View File

@ -0,0 +1,6 @@
apiVersion: v1
kind: Namespace
metadata:
name: outline
labels:
istio-injection: enabled

View File

@ -0,0 +1,139 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: outline
namespace: outline
spec:
interval: 10m
timeout: 10m
chart:
spec:
chart: outline
version: "0.1.0"
sourceRef:
kind: HelmRepository
name: yc-oci-charts
namespace: flux-system
interval: 10m
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
dependsOn:
- name: istiod
namespace: istio-system
- name: outline-valkey
namespace: outline
values:
universal-chart:
global:
env: infra
image:
name:
infra: cr.yandex/crp3ccidau046kdj8g9q/outlinewiki/outline:1.12.0
envs:
- name: NODE_ENV
value:
_default: production
- name: URL
value:
_default: https://wiki.sarex.space
- name: PORT
value:
_default: "3000"
- name: WEB_CONCURRENCY
value:
_default: "1"
# TLS терминируется на istio ingressgateway
- name: FORCE_HTTPS
value:
_default: "false"
- name: ENABLE_UPDATES
value:
_default: "false"
- name: LOG_LEVEL
value:
_default: info
- name: PGSSLMODE
value:
_default: disable
- name: FILE_STORAGE
value:
_default: s3
- name: AWS_REGION
value:
_default: ru-msk
- name: AWS_S3_UPLOAD_BUCKET_URL
value:
_default: https://hb.ru-msk.vkcloud-storage.ru
- name: AWS_S3_UPLOAD_BUCKET_NAME
value:
_default: sarex-wiki
- name: AWS_S3_FORCE_PATH_STYLE
value:
_default: "true"
- name: AWS_S3_ACL
value:
_default: private
# VK Object Storage документирует presigned PUT; presigned POST не описан
- name: AWS_S3_UPLOAD_METHOD
value:
_default: put
- name: OIDC_DISPLAY_NAME
value:
_default: Sarex IAM
- name: OIDC_AUTH_URI
value:
_default: https://iam.sarex.io/oauth/v2/authorize
- name: OIDC_TOKEN_URI
value:
_default: https://iam.sarex.io/oauth/v2/token
- name: OIDC_USERINFO_URI
value:
_default: https://iam.sarex.io/oidc/v1/userinfo
- name: OIDC_LOGOUT_URI
value:
_default: https://iam.sarex.io/oidc/v1/end_session
- name: OIDC_USERNAME_CLAIM
value:
_default: preferred_username
- name: OIDC_SCOPES
value:
_default: openid profile email offline_access
# SMTP подключается отдельным шагом: добавить SMTP_HOST, SMTP_PORT,
# SMTP_FROM_EMAIL сюда и SMTP_USERNAME, SMTP_PASSWORD в secretEnvs.
secretEnvs:
- name: SECRET_KEY
secretName:
_default: outline
secretKey: SECRET_KEY
- name: UTILS_SECRET
secretName:
_default: outline
secretKey: UTILS_SECRET
- name: DATABASE_URL
secretName:
_default: outline-postgresql
secretKey: url
- name: REDIS_URL
secretName:
_default: outline
secretKey: REDIS_URL
- name: AWS_ACCESS_KEY_ID
secretName:
_default: outline
secretKey: AWS_ACCESS_KEY_ID
- name: AWS_SECRET_ACCESS_KEY
secretName:
_default: outline
secretKey: AWS_SECRET_ACCESS_KEY
- name: OIDC_CLIENT_ID
secretName:
_default: outline
secretKey: OIDC_CLIENT_ID
- name: OIDC_CLIENT_SECRET
secretName:
_default: outline
secretKey: OIDC_CLIENT_SECRET

View File

@ -0,0 +1,62 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: outline-valkey
namespace: outline
spec:
interval: 10m
timeout: 10m
chart:
spec:
chart: valkey
version: "0.1.0"
sourceRef:
kind: HelmRepository
name: yc-oci-charts
namespace: flux-system
interval: 10m
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
values:
fullnameOverride: outline-valkey
image:
registry: cr.yandex
repository: crp3ccidau046kdj8g9q/valkey/valkey
tag: 8.0.2-debian-12-r6
global:
imagePullSecrets:
- istio-registry-secret
security:
allowInsecureImages: true
architecture: standalone
auth:
enabled: true
sentinel: false
existingSecret: outline-valkey
existingSecretPasswordKey: valkey-password
# Outline хранит в Valkey очереди фоновых задач и состояние websocket.
# Персистентность не нужна, вытеснение ключей недопустимо для очередей.
commonConfiguration: |-
appendonly no
save ""
maxmemory 256mb
maxmemory-policy noeviction
primary:
podAnnotations:
sidecar.istio.io/inject: "false"
nodeSelector:
sarex.io/pool: svc
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 384Mi
persistence:
enabled: false
metrics:
enabled: false

View File

@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
patches:
- path: postgresql.yaml

View File

@ -0,0 +1,104 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: postgresql
namespace: postgresql
spec:
interval: 5m
timeout: 2h
install:
timeout: 2h
remediation:
retries: 3
upgrade:
timeout: 2h
remediation:
retries: 3
values:
global:
security:
allowInsecureImages: true
defaultStorageClass: ${STORAGE_CLASS}
postgresql:
auth:
username: ""
database: ""
secretKeys:
userPasswordKey: "postgres-password"
auth:
username: ""
database: ""
secretKeys:
userPasswordKey: "postgres-password"
image:
registry: cr.yandex/crp3ccidau046kdj8g9q
repository: contour/postgresql
tag: 17.0.7
pullPolicy: Always
metrics:
enabled: false
prometheusRule:
enabled: false
primary:
automountServiceAccountToken: true
containerSecurityContext:
readOnlyRootFilesystem: false
persistence:
storageClass: ${STORAGE_CLASS}
size: 20Gi
customLivenessProbe:
exec:
command:
- /bin/sh
- -c
- exec pg_isready -U "postgres" -d postgres -h 127.0.0.1 -p 5432
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 6
customReadinessProbe:
exec:
command:
- /bin/sh
- -c
- exec pg_isready -U "postgres" -d postgres -h 127.0.0.1 -p 5432
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 6
customStartupProbe:
exec:
command:
- /bin/sh
- -c
- exec pg_isready -U "postgres" -d postgres -h 127.0.0.1 -p 5432
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 6
nodeSelector:
dedicated: generic
tolerations: []
contour:
enabled: true
adminUser: "postgres"
vault:
enabled: true
role: postgresql-zitadel
authPath: auth/kubernetes
secretPath: secrets/data/postgresql-zitadel/admin
secretKey: postgres-password
usersSecretPath: secrets/data/zitadel/postgresql
sharedPreloadLibraries: "timescaledb,pg_stat_statements"
databases:
- name: zitadel
user: zitadel
passwordKey: password
extensions: []
restoreFromDump: false

View File

@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
patches:
- path: rabbitmq.yaml

Some files were not shown because too many files have changed in this diff Show More