diff --git a/build/Jenkinsfile b/build/Jenkinsfile index 670b479..ca933e7 100644 --- a/build/Jenkinsfile +++ b/build/Jenkinsfile @@ -1,88 +1,286 @@ -@Library(['jlib']) _ +/* + ! Jenkins Watchdog Pipeline -node("docker") { - // Временная метка в логе Jenkins - timestamps() { - // Цветные букавы в логе Jenkins - ansiColor("xterm"){ - // Получаем актуальную версию репы, где лежит пайп - checkout scm - - env.stand = env.BRANCH_NAME - - if (!(stand in ["prod", "test", "dev"])) { - error("stand не соответствует 'prod', 'test' или 'dev'") - } - - stage("Prepare environments") { - envConfig = "build/vars/build.yaml" - support.getVarsV2(envConfig) - - // пока не будет готов отдельный dev стенд - env.namespace = "${env.namespace}-${stand}" - env.registryContainerName = "${env.registryContainerName}-${stand}" - env.version = sh(script: "git rev-parse HEAD", returnStdout: true).trim() - println "Success prepare" - } - - stage("Scan Image") { -/* Убрал на время для перехода на Helm всех микросервисов - def scannerHome = tool 'SonarScanner'; - // Волшебный ключ -Dsonar.qualitygate.wait=true - withCredentials([string(credentialsId: 'sonarqube-access-personal-account-backend', variable: 'tokenAccess')]) { - sh "${scannerHome}/bin/sonar-scanner -Dsonar.sources=. -Dsonar.projectKey=personal-account-backend -Dsonar.host.url=https://sq.adl.nubes.ru -Dsonar.login=${tokenAccess}" - } + Этот Pipeline реализует сборку на Kubernetes worker-ноде с контролем и завершением со стороны Jenkins master-ноды. + Master отслеживает статус worker'а в реальном времени и завершает процесс в случае ошибки, таймаута или успешного завершения. */ - } - stage("Build image") { - println "Start building image ${env.registryContainerName}:${env.version}" - if (registryRepoPath) - env.imageName = "${registryRepoPath}/${env.registryContainerName}" - else - env.imageName = "${env.registryContainerName}" +// Статусы воркера. Необходимо мастеру для определения состояния джоба +def workerFailed = false +def workerSuccess = false +def DEBUGGING_MODE = false +// Мапа для запуска мастера и воркера параллельно +def parallelSteps = [:] - app = docker.build("${env.imageName}:${env.version}", "--no-cache -f ./build/Dockerfile .") +// Блок констант +// Мапа, в которой будут переменные из vars/build.yaml +buildVars = [:] +buildVars.system = [:] +buildVars.kubeconfig = "config.kube" - println "Start uploading image ${env.registryContainerName}:${env.version} to Nexus" +// Подгрузка либы. Версия в свойствах папки Jenkins +library "jlib" +cmdbVars = constants.cmdbVars - docker.withRegistry("https://${registryUrl}/${registryRepoPath}", "registry-jenkins-cred") { - app.push("${env.version}") - app.push("latest") - } - } +TimeoutTime = [ + time: binding.hasVariable('timeoutTime') ? timeoutTime : (cmdbVars?.system?.timeoutTime ?: 20), + unit: binding.hasVariable('timeoutUnit') ? timeoutUnit : (cmdbVars?.system?.timeoutUnit ?: "MINUTES") +] - stage("Update version in Kubernetes") { - dir ("build") { - withCredentials([vaultString(credentialsId: "${env.vaultPath}", variable: "pem")]) { - sh """ - set +x - echo "${pem}" | base64 -d > auth.config - set -x - """ +parallelSteps["worker"] = { + node("docker") { + timestamps() { + ansiColor("xterm"){ + dir (env.BUILD_NUMBER) { + try { + stage ("Prepare environments") { + // Выкачивание проекта из Git + checkout scm + // Определение типа джобы: + // - сборка и пуш в кубер: DEV / PR + // - проверка образа (из DEV) и пуш в кубер: TEST / PROD + logger.info("Targeting stand for deploy") + // Если PR - в DEV + if (env.CHANGE_ID) + buildVars.gitBranch = "dev" + else + buildVars.gitBranch = env.BRANCH_NAME + + // Проверка на нужные бренчи + if (!(buildVars.gitBranch in ["prod", "test", "dev"])) { + logger.err("Ветка в Git не соответствует 'prod', 'test' или 'dev'", true) } - convertJinjaV2("./helm/values.yaml", debug=true) + envConfig = "build/vars/build.yaml" + support.getVarsAll(envConfig, buildVars) - sh """ - helm upgrade --wait \ - --kubeconfig auth.config \ - --install \ - --namespace ${env.namespace} \ - -f ./helm/values.yaml \ - ${env.appName} ./helm/ - """ + logger.info("Get kubeconfig") + try { + withCredentials([vaultString(credentialsId: "${buildVars.vaultPath}", variable: "pem")]) { + runsh """ + set +x + echo "${pem}" | base64 -d > ${ buildVars.kubeconfig } + set -x + """, true + } + logger.info("kubeconfig getting successfully") + } catch (Exception kubeconfigGetError) { + logger.err("Не удалось получить кубконфиг для подключению к Kubernetes-кластеру. Ошибка: ${kubeconfigGetError.message}", true) + } - sh "kubectl --kubeconfig=auth.config get pods --namespace ${env.namespace}" + logger.info("Getting version...") + try { + version = runsh buildVars.getCommandVersion + logger.info("Version app: ${ version }") + } catch (Exception versionGetError) { + logger.err("Не удалось получить версию приложения. Ошибка: ${versionGetError.message}", true) + } + } + + // Получение токена для авторизации в GITEA + withCredentials([vaultString(credentialsId: "gitea.services.ngcloud.ru-deck-token", variable: "token")]) { GITEA_AUTH_TOKEN = token } + + // Сборка Image (Только DEV) + if (buildVars.gitBranch == "dev") { + if (buildVars.needBuildLib.toBoolean()) { + stage ("Check library") { + headers = [ [ name: "Authorization", value: "Bearer ${ GITEA_AUTH_TOKEN }" ] ] + // Проверка что либа существует + try { + retry(3) { + httpcall.get( url="https://gitea.services.ngcloud.ru/api/v1/packages/deck/npm/%40nubes%2F${ buildVars.app.name }/${ version }", headerList=headers) + } + needToBuildLib = false + } catch (Exception errGetPackage) { + logger.info("Package does not exist. It's OK") + needToBuildLib = true + } + } + stage ("Build library") { + if (needToBuildLib.toBoolean()) { + retry(3) { + try { + docker.build("${ buildVars.registryImageName }:${ version }", "--no-cache --build-arg GITEA_AUTH_TOKEN=${ GITEA_AUTH_TOKEN } -f ./build/Dockerfile_build_lib .") + } catch (Exception errorDocker) { + logger.err("Не удалось собрать библиотеку. Ошибка: ${ errorDocker.message }", true) + } + } + } + } + } + stage ("Build image") { + catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') { + logger.info("Start building image ${ buildVars.registryContainerName }:${ version }") + retry(3) { + try { + app = docker.build("${ buildVars.registryImageName }:${ version }", "--no-cache --build-arg GITEA_AUTH_TOKEN=${ GITEA_AUTH_TOKEN } -f ./build/Dockerfile .") + } catch (Exception errorDocker) { + logger.err("Не удалось собрать основной образ. Ошибка: ${ errorDocker.message }", true) + } + } + } + + logger.info("Start uploading image ${ buildVars.registryImageName }:${ version }") + docker.withRegistry("https://${ buildVars.registryUrl }/${ buildVars.repoPath }", "registry-jenkins-cred") { + // retry на случай если 500 случайно отдаст registry + retry(3) { + try { + app.push("${ version }") + } catch (Exception errorDocker) { + logger.err("Не удалось запушить образ в Registry. Ошибка: ${ errorDocker.message }", true) + } + } + } + } + } + // Проверка Image в Registry (Всё кроме DEV) + if (buildVars.gitBranch != "dev") { + stage("Check if image exist") { + docker.withRegistry("https://${ buildVars.registryUrl }/${ buildVars.repoPath }", "registry-jenkins-cred") { + def img = docker.image("${ buildVars.registryImageName }:${ version }") + // TODO переписать либу docker под себя + // try/catch не поможет, ошибка выведет всегда 'script returned exit code 1' + // retry на случай если 500 случайно отдаст registry + retry(3) { + try { + img.pull() + } catch (Exception errorDocker) { + logger.err("Не удалось получить образ из Registry. Ошибка: ${ errorDocker.message }", true) + } + } + } + } + } + // Деплой в Kubernetes (все стенды) + stage("Deploy to K8s test") { + logger.info("Check exist pods in k8s...") + retry(3) { + runsh "kubectl --kubeconfig=${ buildVars.kubeconfig } --namespace ${ buildVars.namespace } get po" + } + + logger.info("Prepare list of args on helm...") + commandArgs = [ + "--set deployment.image.repository=${ buildVars.registryUrl }/${ buildVars.registryImageName }", + "--set deployment.readinessProbe.httpGet.path=${ buildVars.app.health }", + "--set deployment.containerPort=${ buildVars.app.port }", + "--set deployment.resources.requests.cpu=${ buildVars.app.cpu }m", + "--set deployment.resources.requests.memory=${ buildVars.app.mem }Mi", + "--set deployment.resources.limits.cpu=${ buildVars.app.cpu }m", + "--set deployment.resources.limits.memory=${ buildVars.app.mem }Mi", + + "--set deployment.image.tag=${ version }", + "--set stand=${ buildVars.gitBranch }" + ] + // Если включен Vault + if (buildVars.needStoreVaultSecret.toBoolean()) { + commandArgs.add("--set vault.secretStore=${ buildVars.namespace }") + commandArgs.add("--set serviceAccountRole=${ buildVars.namespace }-sa") + commandArgs.add("--set vault.secrets=\"{${ buildVars.storedSecretsList.join(',') }}\"") + commandArgs.add("--set vault.enable=true") + } else { + commandArgs.add("--set vault.enable=false") + } + + installArgs = [ + "--kubeconfig ${ buildVars.kubeconfig }", + "--install", + "--namespace ${ buildVars.namespace }", + ] + + cmdTemplate = "helm template ${commandArgs.join(' ')} ./build/helm/" + cmd = "helm upgrade ${ buildVars.app.name } ${installArgs.join(' ')} ${commandArgs.join(' ')} ./build/helm/" + logger.info("""Command for push... + ${cmd} + """) + + logger.info("Template helm-release...") + runsh cmdTemplate + + logger.info("Push helm-release...") + retry(3) { + // От того, что Helm-чарт будет ждать, мало что изменится + runsh cmd + } + + logger.info("Check exist pods in k8s...") + retry(3) { + runsh "kubectl --kubeconfig=${ buildVars.kubeconfig } --namespace ${ buildVars.namespace } get po" + } + + // Нужны проверки после установки + buildVars.application = [:] + buildVars.application.typeOfProject = "deployments.apps" + buildVars.application.namespace = buildVars.namespace + + // sleep ибо загрузка манифестов в K8S занимает какое-то время + sleep(5) + try { + k8sStagesV2.correctReplicaActive(cmdbVars=buildVars, applicationName=buildVars.app.name) + // Чтобы не оставлять мусора за собой в эвентах + sh "kubectl --kubeconfig=${ buildVars.kubeconfig } --namespace ${ buildVars.namespace } delete events --all" + } catch (Exception errorRun) { + logger.info("Не удалось произвести проверку работы микросервиса. Дебаг:") + runsh "kubectl --kubeconfig=${ buildVars.kubeconfig } --namespace ${ buildVars.namespace } events | grep ${ buildVars.app.name }" + runsh "kubectl --kubeconfig=${ buildVars.kubeconfig } --namespace ${ buildVars.namespace } logs -l 'app=${ buildVars.app.name }'" + error("Не удалось произвести проверку работы микросервиса. Детали в логах pipeline") + } + } + + currentBuild.result = 'SUCCESS' + } + catch (Exception err) { + logger.err("Произошла ошибка") + logger.err(err.message, true) + currentBuild.description = err.message + currentBuild.result = "FAILURE" + } + finally { + if (currentBuild.result == 'FAILURE') { + echo "Worker stage действительно упал — ставим флаг workerFailed" + workerFailed = true + } else if (currentBuild.result == 'SUCCESS') { + echo "Worker stage завершился успешно - ставим флаг workerSuccess" + workerSuccess = true + } else { + echo "Неопознаный currentBuild.result: ${currentBuild.result} — ставим флаг workerFailed" + workerFailed = true + } + runsh "rm -rf ${env.BUILD_NUMBER}" + } + }}} + } +} + +parallelSteps["master"] = { + node("master") { + try { + stage ("Master: start watchdog") { + timeout(time: TimeoutTime.time, unit: TimeoutTime.unit) { + while (true) { + // Следим за окончанием сборки + if (DEBUGGING_MODE) { + sleep 1 + // Только в режиме отладки используем echo + echo "DEBUG: workerFailed = ${workerFailed}" + echo "DEBUG: workerSuccess = ${workerSuccess}" + } + // Проверка флагов без использования шагов Jenkins + if (workerFailed) { + echo "Watchdog: обнаружен сбой в воркере" + break + } else if (workerSuccess) { + echo "Watchdog: воркер завершил работу в Jenkins" + break + } + } } } - - println "Success build job. Now start cleanup" - - cleanWs( - deleteDirs: true, - disableDeferredWipeout: true - ) + runsh "rm -rf ${env.BUILD_NUMBER}" + } + catch (Exception masterErrorTimeout) { + logger.err("Ошибка по таймауту") } } } + +parallel parallelSteps \ No newline at end of file diff --git a/build/helm/templates/deployment.yaml b/build/helm/templates/deployment.yaml index d64ee20..74f7a0d 100644 --- a/build/helm/templates/deployment.yaml +++ b/build/helm/templates/deployment.yaml @@ -1,53 +1,49 @@ +--- apiVersion: apps/v1 kind: Deployment metadata: labels: - app: "{{ .Chart.Name }}" - stand: "{{ .Values.stand }}" - name: "{{ .Chart.Name }}" + app: '{{ .Chart.Name }}' + stand: '{{ .Values.stand }}' + name: '{{ .Chart.Name }}' spec: replicas: 1 selector: matchLabels: - app: "{{ .Chart.Name }}" - stand: "{{ .Values.stand }}" + app: '{{ .Chart.Name }}' + stand: '{{ .Values.stand }}' template: metadata: labels: - app: "{{ .Chart.Name }}" - stand: "{{ .Values.stand }}" + app: '{{ .Chart.Name }}' + stand: '{{ .Values.stand }}' contragentCode: 'WZ01112' billingObject: 'None' spec: - {{- if .Values.vault.enabled }} - serviceAccountName: "{{ .Values.vault.serviceAccountName }}" + {{- if .Values.vault.enable }} + serviceAccountName: '{{ .Values.serviceAccountRole }}' {{- end }} containers: - # Основное приложение - - name: app - image: "{{ .Values.mainContainer.image.repository }}:{{ .Values.mainContainer.image.tag }}" + - image: '{{ .Values.deployment.image.repository }}:{{.Values.deployment.image.tag }}' imagePullPolicy: IfNotPresent + name: app ports: - - containerPort: {{ .Values.mainContainer.containerPort }} - protocol: TCP - resources: - {{- toYaml .Values.mainContainer.resources | nindent 12 }} + - containerPort: {{ .Values.deployment.containerPort }} + protocol: TCP readinessProbe: - failureThreshold: 3 - initialDelaySeconds: 10 - periodSeconds: 30 - successThreshold: 1 - timeoutSeconds: 2 - {{- toYaml .Values.mainContainer.readinessProbe | nindent 12 }} + {{- toYaml (omit .Values.deployment.readinessProbe "httpGet") | nindent 12 }} + httpGet: + {{- toYaml .Values.deployment.readinessProbe.httpGet | nindent 14 }} + port: {{ .Values.deployment.containerPort }} livenessProbe: - failureThreshold: 3 - initialDelaySeconds: 30 - periodSeconds: 10 - successThreshold: 1 - timeoutSeconds: 1 - {{- toYaml .Values.mainContainer.livenessProbe | nindent 12 }} - {{- if .Values.vault.enabled }} + {{- toYaml (omit .Values.deployment.livenessProbe "tcpSocket") | nindent 12 }} + tcpSocket: + port: {{ .Values.deployment.containerPort }} + + resources: + {{- toYaml .Values.deployment.resources | nindent 12 }} + {{- if .Values.vault.enable }} envFrom: - - secretRef: - name: "{{ .Values.vault.target.name }}" + - secretRef: + name: '{{ .Chart.Name }}-secrets' {{- end }} diff --git a/build/helm/templates/service.yaml b/build/helm/templates/service.yaml index ad797a6..2c80267 100644 --- a/build/helm/templates/service.yaml +++ b/build/helm/templates/service.yaml @@ -2,15 +2,15 @@ apiVersion: v1 kind: Service metadata: - name: "{{ .Chart.Name }}" + name: '{{ .Chart.Name }}' labels: - app: "{{ .Chart.Name }}" - stand: "{{ .Values.stand }}" + app: '{{ .Chart.Name }}' + stand: '{{ .Values.stand }}' spec: ports: - - port: {{ .Values.mainContainer.containerPort }} - targetPort: {{ .Values.mainContainer.containerPort }} - protocol: TCP + - port: {{ .Values.deployment.containerPort }} + targetPort: {{ .Values.deployment.containerPort }} + protocol: TCP selector: - app: "{{ .Chart.Name }}" - stand: "{{ .Values.stand }}" \ No newline at end of file + app: '{{ .Chart.Name }}' + stand: '{{ .Values.stand }}' diff --git a/build/helm/templates/vault.yaml b/build/helm/templates/vault.yaml index cfb542b..0ede229 100644 --- a/build/helm/templates/vault.yaml +++ b/build/helm/templates/vault.yaml @@ -1,20 +1,23 @@ -{{- if .Values.vault.enabled }} +{{- if .Values.vault.enable }} +--- apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: - name: "{{ .Chart.Name }}" + name: '{{ .Chart.Name }}' + labels: + app: '{{ .Chart.Name }}' spec: - refreshInterval: "60s" + refreshInterval: '60s' secretStoreRef: - name: "{{ .Values.vault.secretStore }}" + name: '{{ .Values.vault.secretStore }}' # имя SecretStore kind: SecretStore target: - name: "{{ .Values.vault.target.name }}" + name: '{{ .Chart.Name }}-secrets' # имя будущего секрета kubernetes data: - {{- range .Values.vault.data }} - - secretKey: {{ .secretKey }} + {{- range .Values.vault.secrets }} + - secretKey: {{ . }} remoteRef: - key: "{{ .remoteRef.key }}" - property: "{{ .remoteRef.property }}" - {{- end }} + key: "deck/kubernetes/{{ $.Values.stand }}/{{ $.Chart.Name }}" + property: {{ . }} + {{- end }} {{- end }} \ No newline at end of file diff --git a/build/helm/values.yaml b/build/helm/values.yaml index 6c1bc38..7deab5f 100644 --- a/build/helm/values.yaml +++ b/build/helm/values.yaml @@ -1,88 +1,42 @@ -# -# Данный конфигурационный файл не является конечным исполнением -# Параметры подставлены исключительно для тестов и могут быть измененены в соответствии с Pipeline -# +# Пример для DEV сборки +stand: dev -stand: {{ stand }} - -mainContainer: - ###### Репозиторий +deployment: image: - repository: "{{ registryUrl }}/{{ imageName }}" - tag: {{ version }} - containerPort: {{ appPort }} - ###### Ресурсы + repository: drn.tst.nubes.ru/deck-auth-api-test + tag: $VERSION + containerPort: 8080 resources: - requests: - cpu: "500m" - memory: "1024Mi" + requests: # Начальные запросы + cpu: "500m" + memory: "256Mi" limits: - cpu: "1000m" - memory: "1024Mi" - ###### Пробы контейнера + cpu: "2" # Максимальные лимиты + memory: "1024Mi" readinessProbe: - tcpSocket: - port: {{ appPort }} - livenessProbe: + failureThreshold: 5 + initialDelaySeconds: 10 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 5 httpGet: - path: /api/v1 - port: {{ appPort }} + path: /api/v1/health scheme: HTTP - -# Для Vault есть условие -# Предварительно в Namespace должен быть создан SecretStore -# -# Читать: https://confluence.ad.nubes.ru/pages/viewpage.action?pageId=58626585 -# (Вариант 2. Используя external-operator) + livenessProbe: + failureThreshold: 5 + initialDelaySeconds: 30 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 1 vault: - secretStore: "{{ namespace }}" - enabled: true - serviceAccountName: "{{ namespace }}-sa" - target: - name: "{{ appName }}-envs" - data: - - secretKey: LUCEE_EXTENSIONS - remoteRef: - key: "deck/kubernetes/{{ stand}}/{{ appName }}" - property: LUCEE_EXTENSIONS - - - secretKey: ORCHESTRATOR_AUTH - remoteRef: - key: "deck/kubernetes/{{ stand}}/{{ appName }}" - property: ORCHESTRATOR_AUTH - - - secretKey: cfconfig_datasources_cmdb_database - remoteRef: - key: "deck/kubernetes/{{ stand}}/{{ appName }}" - property: cfconfig_datasources_cmdb_database - - - secretKey: cfconfig_datasources_cmdb_dbdriver - remoteRef: - key: "deck/kubernetes/{{ stand}}/{{ appName }}" - property: cfconfig_datasources_cmdb_dbdriver - - - secretKey: cfconfig_datasources_cmdb_host - remoteRef: - key: "deck/kubernetes/{{ stand}}/{{ appName }}" - property: cfconfig_datasources_cmdb_host - - - secretKey: cfconfig_datasources_cmdb_name - remoteRef: - key: "deck/kubernetes/{{ stand}}/{{ appName }}" - property: cfconfig_datasources_cmdb_name - - - secretKey: cfconfig_datasources_cmdb_password - remoteRef: - key: "deck/kubernetes/{{ stand}}/{{ appName }}" - property: cfconfig_datasources_cmdb_password - - - secretKey: cfconfig_datasources_cmdb_port - remoteRef: - key: "deck/kubernetes/{{ stand}}/{{ appName }}" - property: cfconfig_datasources_cmdb_port - - - secretKey: cfconfig_datasources_cmdb_username - remoteRef: - key: "deck/kubernetes/{{ stand}}/{{ appName }}" - property: cfconfig_datasources_cmdb_username + enable: true + secretStore: deck-test + secrets: + - VITE_BACKEND_HOST + - VITE_AUTH_HOST + - VITE_KEYCLOAK_CLIENT_ID + - VITE_KEYCLOAK_REALM + - VITE_KEYCLOAK_REDIRECT_URI + - VITE_KEYCLOAK_URL + - VITE_KEYCLOAK_CLIENT_SECRET diff --git a/build/vars/build.yaml b/build/vars/build.yaml index ade0578..5079400 100644 --- a/build/vars/build.yaml +++ b/build/vars/build.yaml @@ -1,14 +1,48 @@ -main: - registryUrl: 'registry.ngcloud.ru' # Где хранится приложение - registryRepoPath: 'deck' # Где хранится приложение (registry.ngcloud.ru/deck) - appName: "svc-api" # наименование контейнера в K8S - registryContainerName: "deck-{{ appName }}" # Наименование приложения в Nexus - vaultPath: "config.deck-{{ appName }}-{{ stand }}" # Путь где лежит инфраструктурный kubeconfig для установки Helm-чарта - namespace: "deck" # Namespace приложения, где он будет развёрнут - appPort: 8080 # Порт, на котором работает приложение +##### Переменные ##### +###################### +app: + # Имя приложения / Имя микросервиса + name: "svc-api" + # Порт на котором приложение будет работать + port: 8080 + # Health-Check приложения + health: "/api/v1" + # CPU пода (milicores) + cpu: 1000 + # Mem пода (megabytes) + mem: 1024 -version: - release: 0 - major: 0 - minor: "{{ BUILD_NUMBER }}" - version: "{{ release }}.{{ major }}.{{ minor }}" +# Получение версии приложения +# Используется для построения дашбордов / публикации в Registry +getCommandVersion: "awk -F'\"' '/APIVersion/ {print \\$2; exit}' v1/Application.cfc" + +# Если включено, то необходимо сделать файл Dockerfile_build_lib +# Либа будет загружена в deck/npm/nubes/{appName}/{version} +needBuildLib: false +# Нужно ли хранить секреты в Vault +needStoreVaultSecret: true +# Наименование key, которые нужно забрать из Vault +storedSecretsList: + - "LUCEE_EXTENSIONS" + - "ORCHESTRATOR_AUTH" + - "cfconfig_datasources_cmdb_database" + - "cfconfig_datasources_cmdb_dbdriver" + - "cfconfig_datasources_cmdb_host" + - "cfconfig_datasources_cmdb_name" + - "cfconfig_datasources_cmdb_port" + - "cfconfig_datasources_cmdb_username" + - "cfconfig_datasources_cmdb_password" + +##### Константы ##### +##################### +# Путь до секрета в Vault +vaultPath: "config.deck-${ app.name }-${ gitBranch }" +# Где хранится образ (Registry.app) +registryUrl: "registry.ngcloud.ru" +registryRepoPath: "deck" +registryContainerName: "deck-${ app.name }" +registryImageName: "${ registryRepoPath ? registryRepoPath + '/' + registryContainerName : registryContainerName }" + +# В какой namespace попадает проект в Kubernetes (по хорошему нужно изменить) +# Ибо счас всё хранится в одном кубере. Кубер умрёт - 3 сренда в OUT +namespace: "deck-${ gitBranch }" \ No newline at end of file