4 Commits
4 .. 8

Author SHA1 Message Date
Hermes Agent 72548b798a fix: sourceUrl опциональный (воркер сам строит URL из itemId)
Build Media Mirror API / Build and publish (release) Successful in 29s
2026-08-10 23:29:06 +03:00
Hermes Agent 342ceee28d fix: helm-деплой — ключи секрета S3 (accessKey/secretKey)
Build Media Mirror API / Build and publish (release) Successful in 29s
2026-08-10 22:36:02 +03:00
Hermes Agent ecf82b0e2e helm: ingress для внешнего доступа
Build Media Mirror API / Build and publish (release) Successful in 31s
2026-08-10 22:31:06 +03:00
Hermes Agent c100b52720 helm: секреты API_KEY (X-API-Key) и JELLYFIN_API_KEY (сканер)
Build Media Mirror API / Build and publish (release) Successful in 29s
2026-08-10 22:28:20 +03:00
7 changed files with 53 additions and 4 deletions
+2
View File
@@ -9,8 +9,10 @@ data:
forward-headers-strategy: framework forward-headers-strategy: framework
app: app:
api-key: ${API_KEY}
jellyfin: jellyfin:
url: {{ $.Values.app.jellyfin.url | quote }} url: {{ $.Values.app.jellyfin.url | quote }}
api-key: ${JELLYFIN_API_KEY}
s3: s3:
url: {{ $.Values.app.s3.url | quote }} url: {{ $.Values.app.s3.url | quote }}
access-key: ${S3_ACCESS_KEY} access-key: ${S3_ACCESS_KEY}
+12 -2
View File
@@ -69,16 +69,26 @@ spec:
key: dbPassword key: dbPassword
- name: DB_URL - name: DB_URL
value: "jdbc:postgresql://{{ $.Values.db.host }}:{{ $.Values.db.port }}/{{ $.Values.db.name }}" value: "jdbc:postgresql://{{ $.Values.db.host }}:{{ $.Values.db.port }}/{{ $.Values.db.name }}"
- name: API_KEY
valueFrom:
secretKeyRef:
name: {{ $.Release.Name }}-{{ $.Chart.Name }}-secret
key: apiKey
- name: JELLYFIN_API_KEY
valueFrom:
secretKeyRef:
name: {{ $.Release.Name }}-{{ $.Chart.Name }}-secret
key: jellyfinApiKey
- name: S3_ACCESS_KEY - name: S3_ACCESS_KEY
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ $.Release.Name }}-{{ $.Chart.Name }}-secret name: {{ $.Release.Name }}-{{ $.Chart.Name }}-secret
key: app.s3.accessKey key: accessKey
- name: S3_SECRET_KEY - name: S3_SECRET_KEY
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ $.Release.Name }}-{{ $.Chart.Name }}-secret name: {{ $.Release.Name }}-{{ $.Chart.Name }}-secret
key: app.s3.secretKey key: secretKey
volumeMounts: volumeMounts:
- mountPath: '/opt/app/config' - mountPath: '/opt/app/config'
name: application-properties-volume name: application-properties-volume
+17
View File
@@ -0,0 +1,17 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: "{{ $.Release.Name }}-{{ $.Chart.Name }}"
annotations: {}
spec:
rules:
- host: {{.Values.ingress.host }}
http:
paths:
- backend:
service:
name: "{{ $.Release.Name }}-{{ $.Chart.Name }}"
port:
number: {{ .Values.port }}
path: /
pathType: Prefix
+2
View File
@@ -8,3 +8,5 @@ data:
dbPassword: {{ (required "DB password не установлен" $.Values.db.password) | b64enc | quote }} dbPassword: {{ (required "DB password не установлен" $.Values.db.password) | b64enc | quote }}
accessKey: {{ (required "Accesskey не установлен" $.Values.app.s3.accessKey) | b64enc | quote }} accessKey: {{ (required "Accesskey не установлен" $.Values.app.s3.accessKey) | b64enc | quote }}
secretKey: {{ (required "Secretkey не установлен" $.Values.app.s3.secretKey) | b64enc | quote }} secretKey: {{ (required "Secretkey не установлен" $.Values.app.s3.secretKey) | b64enc | quote }}
apiKey: {{ (required "ApiKey не установлен" $.Values.app.apiKey) | b64enc | quote }}
jellyfinApiKey: {{ (required "Jellyfin ApiKey не установлен" $.Values.app.jellyfin.apiKey) | b64enc | quote }}
+4
View File
@@ -23,8 +23,10 @@ db:
maxConnections: 10 maxConnections: 10
app: app:
apiKey: null
jellyfin: jellyfin:
url: null url: null
apiKey: null
s3: s3:
url: null url: null
accessKey: null accessKey: null
@@ -35,3 +37,5 @@ app:
securityContext: securityContext:
privileged: false privileged: false
ingress:
host: null
@@ -7,7 +7,6 @@ import kotlinx.serialization.Serializable
data class CreateMirrorRequest( data class CreateMirrorRequest(
@field:NotBlank(message = "itemId must not be blank") @field:NotBlank(message = "itemId must not be blank")
val itemId: String, val itemId: String,
@field:NotBlank(message = "sourceUrl must not be blank") val sourceUrl: String = "",
val sourceUrl: String,
val sourceType: String = "jellyfin", val sourceType: String = "jellyfin",
) )
@@ -83,6 +83,21 @@ class MirrorControllerTest : AbstractIntegrationTest() {
assertEquals(1, count) assertEquals(1, count)
} }
@Test
fun `POST mirror without sourceUrl creates a job`() {
mockMvc.perform(
post("/api/mirror")
.contentType(MediaType.APPLICATION_JSON)
.content("""{"itemId":"no-url-id"}"""),
).andExpect(status().isCreated)
val response = json.decodeFromString<ByItemResponse>(
bodyOf(mockMvc.perform(get("/api/mirror/by-item/no-url-id")).andExpect(status().isOk).andReturn()),
)
assertEquals("no-url-id", response.itemId)
assertEquals("new", response.status)
}
@Test @Test
fun `POST mirror returns 400 on blank itemId`() { fun `POST mirror returns 400 on blank itemId`() {
postCreate("", "https://source.example/stream") postCreate("", "https://source.example/stream")