Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/deploy_images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ on:
default: true
description: Build new image of save-orchestrator
required: false
sandbox:
type: boolean
default: true
description: Build new image of save-sandbox
required: false
preprocessor:
type: boolean
default: true
Expand All @@ -57,7 +62,7 @@ jobs:
name: Prepare to build
working-directory: save-cloud
run: |
echo GRADLE_TASKS=:api-gateway:bootBuildImage :save-backend:bootBuildImage :save-frontend:buildImage :save-orchestrator:bootBuildImage :save-preprocessor:bootBuildImage >> $GITHUB_ENV
echo GRADLE_TASKS=:api-gateway:bootBuildImage :save-backend:bootBuildImage :save-frontend:buildImage :save-orchestrator:bootBuildImage :save-sandbox:bootBuildImage :save-preprocessor:bootBuildImage >> $GITHUB_ENV
- if: github.event_name == 'workflow_dispatch'
name: Prepare to build from branch
working-directory: save-cloud
Expand All @@ -69,6 +74,7 @@ jobs:
if ${{ inputs.backend }} == 'true'; then GRADLE_TASKS+=":save-backend:bootBuildImage "; fi
if ${{ inputs.frontend }} == 'true'; then GRADLE_TASKS+=":save-frontend:buildImage "; fi
if ${{ inputs.orchestrator }} == 'true'; then GRADLE_TASKS+=":save-orchestrator:bootBuildImage "; fi
if ${{ inputs.sandbox }} == 'true'; then GRADLE_TASKS+=":save-sandbox:bootBuildImage "; fi
if ${{ inputs.preprocessor }} == 'true'; then GRADLE_TASKS+=":save-preprocessor:bootBuildImage "; fi
echo GRADLE_TASKS=$GRADLE_TASKS >> $GITHUB_ENV
- name: checkout save-core
Expand Down
2 changes: 2 additions & 0 deletions api-gateway/src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ gateway:
url: http://localhost:5800
frontend:
url: http://localhost:5810
sandbox:
url: http://localhost:5400
spring:
security:
oauth2:
Expand Down
10 changes: 10 additions & 0 deletions api-gateway/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ gateway:
url: http://frontend:5810
grafana:
url: http://grafana:9100
sandbox:
url: http://sandbox:5400
management:
endpoints:
web:
Expand Down Expand Up @@ -50,6 +52,14 @@ spring:
uri: ${gateway.grafana.url}
predicates:
- Path=/grafana/**
- id: sandbox-api_route
uri: ${gateway.sandbox.url}
predicates:
- Path=/sandbox/api/**
filters:
# If SESSION cookie is passed to downstream, it is then removed, because downstream discards it
- RemoveRequestHeader=Cookie
- ConvertAuthorizationHeader=
Comment thread
nulls marked this conversation as resolved.

---
spring:
Expand Down
29 changes: 16 additions & 13 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,27 @@ plugins {
}

val profile = properties.getOrDefault("save.profile", "dev") as String
val databaseCredentials = getDatabaseCredentials(profile)

liquibase {
activities {
val commonArguments = mapOf(
"logLevel" to "info",
"contexts" to when (profile) {
"prod" -> "prod"
"dev" -> "dev"
else -> throw GradleException("Profile $profile not configured to map on a particular liquibase context")
}
)
// Configuring luiquibase
register("main") {
arguments = mapOf(
"changeLogFile" to "db/db.changelog-master.xml",
"url" to databaseCredentials.databaseUrl,
"username" to databaseCredentials.username,
"password" to databaseCredentials.password,
"logLevel" to "info",
"contexts" to when (profile) {
"prod" -> "prod"
"dev" -> "dev"
else -> throw GradleException("Profile $profile not configured to map on a particular liquibase context")
}
)
arguments = mapOf("changeLogFile" to "db/db.changelog-master.xml") +
getBackendDatabaseCredentials(profile).toLiquibaseArguments() +
commonArguments
}
register("sandbox") {
arguments = mapOf("changeLogFile" to "save-sandbox/db/db.changelog-sandbox.xml") +
getSandboxDatabaseCredentials(profile).toLiquibaseArguments() +
commonArguments
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,52 @@ data class DatabaseCredentials(
val databaseUrl: String,
val username: String,
val password: String
)
) {
/**
* @return arguments for liquibase task
*/
fun toLiquibaseArguments(): Map<String, String> = mapOf(
"url" to "$databaseUrl?createDatabaseIfNotExist=true",
"username" to username,
"password" to password,
)
}

/**
* @param profile a profile to get credentials for
* @return an instance of [DatabaseCredentials] for [profile]
* @return an instance of [DatabaseCredentials] for [profile] in backend
*/
@Suppress("AVOID_NULL_CHECKS")
fun Project.getDatabaseCredentials(profile: String): DatabaseCredentials {
val props = java.util.Properties()
fun Project.getBackendDatabaseCredentials(profile: String): DatabaseCredentials = getDatabaseCredentials("save-backend", profile)

val secretsPath = System.getenv("DB_SECRETS_PATH")
if (secretsPath != null) {
/**
* @param profile a profile to get credentials for
* @return an instance of [DatabaseCredentials] for [profile] in sandbox
*/
fun Project.getSandboxDatabaseCredentials(profile: String): DatabaseCredentials = getDatabaseCredentials("save-sandbox", profile)

private fun Project.getDatabaseCredentials(projectName: String, profile: String): DatabaseCredentials {
System.getenv("DB_SECRETS_PATH")?.let { secretsPath ->
// Branch for environment with explicit file with database credentials, e.g. Kubernetes Secrets
val url = file("$secretsPath/spring.datasource.url").readText()
val username = file("$secretsPath/spring.datasource.username").readText()
val password = file("$secretsPath/spring.datasource.password").readText()
return DatabaseCredentials(url, username, password)
} else {
// Branch for other environments, e.g. local deployment or server deployment
file("save-backend/src/main/resources/application-$profile.properties").inputStream().use(props::load)
if (File("${System.getenv("HOME")}/secrets").exists()) {
file("${System.getenv("HOME")}/secrets").inputStream().use(props::load)
}
}
val props = java.util.Properties()
// Branch for other environments, e.g. local deployment or server deployment
file("${projectName}/src/main/resources/application-$profile.properties").inputStream().use(props::load)
Comment thread Fixed
if (File("${System.getenv("HOME")}/secrets").exists()) {
file("${System.getenv("HOME")}/secrets").inputStream().use(props::load)
}

val databaseUrl: String
val databaseUrl: String = props.getProperty("spring.datasource.url")
val username: String
val password: String

if (profile == "prod") {
databaseUrl = props.getProperty("spring.datasource.url")
username = props.getProperty("username")
password = props.getProperty("password")
} else {
databaseUrl = props.getProperty("datasource.dev.url")
Comment thread
nulls marked this conversation as resolved.
username = props.getProperty("spring.datasource.username")
password = props.getProperty("spring.datasource.password")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ fun Project.createStackDeployTask(profile: String) {
| - "3306:3306"
| environment:
| - "MYSQL_ROOT_PASSWORD=123"
| - "MYSQL_DATABASE=save_cloud"
| zookeeper:
| image: confluentinc/cp-zookeeper:latest
| environment:
Expand Down Expand Up @@ -105,6 +104,7 @@ fun Project.createStackDeployTask(profile: String) {
FRONTEND_TAG=${defaultVersionOrProperty("frontend.dockerTag")}
GATEWAY_TAG=${defaultVersionOrProperty("gateway.dockerTag")}
ORCHESTRATOR_TAG=${defaultVersionOrProperty("orchestrator.dockerTag")}
SANDBOX_TAG=${defaultVersionOrProperty("sandbox.dockerTag")}
PREPROCESSOR_TAG=${defaultVersionOrProperty("preprocessor.dockerTag")}
PROFILE=$profile
""".trimIndent()
Expand Down Expand Up @@ -140,6 +140,7 @@ fun Project.createStackDeployTask(profile: String) {
Files.createDirectories(configsDir.resolve("backend"))
Files.createDirectories(configsDir.resolve("gateway"))
Files.createDirectories(configsDir.resolve("orchestrator"))
Files.createDirectories(configsDir.resolve("sandbox"))
Files.createDirectories(configsDir.resolve("preprocessor"))
}
description =
Expand Down Expand Up @@ -225,6 +226,7 @@ fun Project.createStackDeployTask(profile: String) {
"up",
"-d",
"orchestrator",
"sandbox",
"backend",
"frontend",
"preprocessor"
Expand All @@ -243,7 +245,7 @@ fun Project.createStackDeployTask(profile: String) {
project(componentName).tasks.named<BootBuildImage>("bootBuildImage")
dependsOn(buildTask)
val serviceName = when (componentName) {
"save-backend", "save-frontend", "save-orchestrator", "save-preprocessor" -> "save_${componentName.substringAfter("save-")}"
"save-backend", "save-frontend", "save-orchestrator", "save-sandbox", "save-preprocessor" -> "save_${componentName.substringAfter("save-")}"
"api-gateway" -> "save_gateway"
else -> error("Wrong component name $componentName")
}
Expand Down
26 changes: 21 additions & 5 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,34 @@ services:
labels:
- "prometheus-job=save-orchestrator"
logging: *loki-logging-jvm
sandbox:
image: ghcr.io/saveourtool/save-sandbox:${SANDBOX_TAG}
Comment thread
nulls marked this conversation as resolved.
user: root # to access host's docker socket
environment:
- "SPRING_PROFILES_ACTIVE=${PROFILE},docker-secrets"
secrets:
- db_username
- db_password
ports:
- "5400:5400"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- /home/saveu/configs/sandbox:/home/cnb/config
- save-fs-storage:/home/cnb/files
- save-tmp-resources:/tmp
extra_hosts:
- "host.docker.internal:host-gateway"
deploy:
labels:
- "prometheus-job=save-sandbox"
logging: *loki-logging-jvm
backend:
image: ghcr.io/saveourtool/save-backend:${BACKEND_TAG}
environment:
- "SPRING_PROFILES_ACTIVE=${PROFILE},secure,docker-secrets"
- "MYSQL_USER=/run/secrets/db_username"
Comment thread
nulls marked this conversation as resolved.
- "MYSQL_PASSWORD_FILE=/run/secrets/db_password"
secrets:
- db_username
- db_password
- db_url
volumes:
- save-fs-storage:/home/cnb/files
- /home/saveu/configs/backend:/home/cnb/config
Expand Down Expand Up @@ -144,5 +162,3 @@ secrets:
external: true
db_username:
external: true
db_url:
external: true
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ spring-boot-starter-test = { module = "org.springframework.boot:spring-boot-star
spring-boot-starter-data-jpa = { module = "org.springframework.boot:spring-boot-starter-data-jpa" }
spring-boot-starter-quartz = { module = "org.springframework.boot:spring-boot-starter-quartz" }
spring-boot-starter-security = { module = "org.springframework.boot:spring-boot-starter-security" }
spring-boot = { module = "org.springframework.boot:spring-boot" }
spring-boot-configuration-processor = { module = "org.springframework.boot:spring-boot-configuration-processor", version.ref = "spring-boot" }
spring-security-core = { module = "org.springframework.security:spring-security-core" }
spring-security-oauth2-client = { module = "org.springframework.security:spring-security-oauth2-client" }
Expand Down
2 changes: 1 addition & 1 deletion save-backend/src/main/resources/META-INF/spring.factories
Original file line number Diff line number Diff line change
@@ -1 +1 @@
org.springframework.boot.env.EnvironmentPostProcessor=com.saveourtool.save.backend.postprocessor.DockerSecretsDatabaseProcessor
org.springframework.boot.env.EnvironmentPostProcessor=com.saveourtool.save.spring.postprocessor.DockerSecretsDatabaseProcessor
3 changes: 0 additions & 3 deletions save-backend/src/main/resources/application-dev.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
spring.liquibase.enabled=false
# `mysql` is resolved when running mysql in docker-compose, change to `datasource.dev.url` if running backend via `bootRun` or from IDE
spring.datasource.url=jdbc:mysql://localhost:3306/save_cloud
datasource.dev.url=jdbc:mysql://localhost:3306/save_cloud
spring.datasource.username=root
spring.datasource.password=123
backend.url=http://host.docker.internal:${server.port}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
spring.liquibase.enabled=false
spring.datasource.url=jdbc:mysql://192.168.0.250:3306/save_cloud
spring.quartz.job-store-type=jdbc
spring.quartz.jdbc.initialize-schema=ALWAYS
3 changes: 2 additions & 1 deletion save-backend/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ backend.preprocessorUrl=http://preprocessor:5200
backend.orchestratorUrl=http://orchestrator:5100
backend.initialBatchSize=100
backend.fileStorage.location=/home/cnb/files
server.port = 5800
server.port=5800
server.error.path=/error
management.endpoints.web.exposure.include=health,info,prometheus,quartz
server.error.include-message=always
Expand All @@ -20,3 +20,4 @@ spring.jpa.properties.hibernate.order_updates=true
logging.level.org.hibernate.engine.internal.StatisticalLoggingSessionEventListener=WARN
spring.cloud.kubernetes.enabled=false
spring.codec.max-in-memory-size=100MB
spring.liquibase.enabled=false
10 changes: 5 additions & 5 deletions save-cloud-charts/save-cloud/templates/backend-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ spec:
env:
{{- include "spring-boot.common.env" (merge (dict "service" .Values.backend) .) | nindent 12 }}
- name: DATABASE_SECRETS_PATH
value: {{ .Values.backend.dbPasswordFile }}
value: {{ .Values.mysql.dbPasswordFile }}
- name: JAVA_TOOL_OPTIONS
value: -XX:ReservedCodeCacheSize=48M
volumeMounts:
- {{ include "spring-boot.config-volume-mount" . | indent 14 | trim }}
- name: fs-storage
mountPath: /home/cnb/files
- name: database-secret
mountPath: {{ .Values.backend.dbPasswordFile }}
mountPath: {{ .Values.mysql.dbPasswordFile }}
{{- include "spring-boot.management" .Values.backend | nindent 10 }}
resources:
limits:
Expand Down Expand Up @@ -62,7 +62,7 @@ spec:
runAsUser: 1001
runAsGroup: 1001
args:
- --url=$(DB_URL)
- --url=$(DB_URL)?createDatabaseIfNotExist=true
- --changeLogFile=db/db.changelog-master.xml
- --username=$(DB_USERNAME)
- --password=$(DB_PASSWORD)
Expand All @@ -82,7 +82,7 @@ spec:
valueFrom:
secretKeyRef:
name: db-secrets
key: spring.datasource.url
key: spring.datasource.backend-url
- name: DB_USERNAME
valueFrom:
secretKeyRef:
Expand All @@ -96,7 +96,7 @@ spec:
volumeMounts:
- mountPath: /liquibase/changelog
name: migrations-data
- mountPath: {{ .Values.backend.dbPasswordFile }}
- mountPath: {{ .Values.mysql.dbPasswordFile }}
name: database-secret
{{ end }}
volumes:
Expand Down
9 changes: 4 additions & 5 deletions save-cloud-charts/save-cloud/templates/mysql-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ kind: Secret
metadata:
name: db-secrets
stringData:
spring.datasource.url: 'jdbc:mysql://mysql-service:3306/{{ .Values.mysql.schema }}'
spring.datasource.backend-url: 'jdbc:mysql://mysql-service:3306/{{ .Values.mysql.backend_schema }}'
spring.datasource.sandbox-url: 'jdbc:mysql://mysql-service:3306/{{ .Values.mysql.sandbox_schema }}'
spring.datasource.username: root
spring.datasource.password: '123'
spring.datasource.password: {{ .Values.mysql.root_password }}

---
{{ end }}
Expand Down Expand Up @@ -36,9 +37,7 @@ spec:
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: '123'
- name: MYSQL_DATABASE
value: save_cloud
value: {{ .Values.mysql.root_password }}
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
Expand Down
25 changes: 25 additions & 0 deletions save-cloud-charts/save-cloud/templates/sandbox-configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Values.sandbox.name }}-config
data:
application.properties: |
sandbox.backendUrl=N/A

sandbox.kubernetes.apiServerUrl=http://kubernetes.default.svc
sandbox.kubernetes.serviceAccount=${POD_SERVICE_ACCOUNT}
sandbox.kubernetes.namespace=${POD_NAMESPACE}

server.shutdown=graceful
management.endpoints.web.exposure.include=*
sandbox.agent-settings.orchestrator-url=http://{{ .Values.sandbox.name }}
sandbox.agent-settings.backend-url=http://{{ .Values.sandbox.name }}
sandbox.agent-settings.debug=true

sandbox.test-resources.tmp-path=/tmp/save/resources

logging.level.com.saveourtool.save.orchestrator.kubernetes=DEBUG

{{ if .Values.sandbox.applicationProperties }}
{{- .Values.sandbox.applicationProperties | nindent 4 }}
{{ end }}
Loading