From 2d4ed45f916af91e24a37a05420e3ffb59f1f263 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 10 Jul 2026 08:54:28 +0000 Subject: [PATCH] Release gohoarder 0.1.148 --- charts/gohoarder/Chart.yaml | 4 +- .../templates/ingressroute-traefik.yaml | 129 ++++++++++++++++++ charts/gohoarder/values.yaml | 18 ++- charts/packages/gohoarder-0.1.148.tgz | Bin 0 -> 19035 bytes index.yaml | 28 +++- 5 files changed, 172 insertions(+), 7 deletions(-) create mode 100644 charts/gohoarder/templates/ingressroute-traefik.yaml create mode 100644 charts/packages/gohoarder-0.1.148.tgz diff --git a/charts/gohoarder/Chart.yaml b/charts/gohoarder/Chart.yaml index cac4dd0..80d4e72 100644 --- a/charts/gohoarder/Chart.yaml +++ b/charts/gohoarder/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: gohoarder description: A universal package cache proxy supporting npm, PyPI, and Go modules with security scanning type: application -version: 0.1.147 -appVersion: "0.1.147" +version: 0.1.148 +appVersion: "0.1.148" keywords: - package-manager - cache diff --git a/charts/gohoarder/templates/ingressroute-traefik.yaml b/charts/gohoarder/templates/ingressroute-traefik.yaml new file mode 100644 index 0000000..586bab6 --- /dev/null +++ b/charts/gohoarder/templates/ingressroute-traefik.yaml @@ -0,0 +1,129 @@ +{{- if and .Values.ingress.enabled (eq .Values.ingress.className "traefik") -}} +--- +# Traefik IngressRoute for package registry paths +# This handles package downloads including scoped packages with encoded slashes +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: {{ include "gohoarder.fullname" . }}-packages + labels: + {{- include "gohoarder.labels" . | nindent 4 }} +spec: + entryPoints: + - websecure + routes: + # Package registry routes with high priority + # PathPrefix matching to avoid Go's encoded slash rejection in regex + - match: Host(`{{ .Values.ingress.host | default (printf "%s.%s" "gohoarder" .Values.global.domain) }}`) && PathPrefix(`/npm/`) + kind: Rule + priority: 100 + services: + - name: {{ include "gohoarder.fullname" . }}-frontend + port: {{ .Values.frontend.service.port }} + middlewares: + - name: {{ include "gohoarder.fullname" . }}-strip-encoded-slash + namespace: {{ .Release.Namespace }} + {{- if .Values.ingress.traefik }} + {{- if .Values.ingress.traefik.middlewares }} + {{- range .Values.ingress.traefik.middlewares }} + - name: {{ . }} + namespace: traefik + {{- end }} + {{- end }} + {{- end }} + + - match: Host(`{{ .Values.ingress.host | default (printf "%s.%s" "gohoarder" .Values.global.domain) }}`) && PathPrefix(`/pypi/`) + kind: Rule + priority: 100 + services: + - name: {{ include "gohoarder.fullname" . }}-frontend + port: {{ .Values.frontend.service.port }} + middlewares: + - name: {{ include "gohoarder.fullname" . }}-strip-encoded-slash + namespace: {{ .Release.Namespace }} + {{- if .Values.ingress.traefik }} + {{- if .Values.ingress.traefik.middlewares }} + {{- range .Values.ingress.traefik.middlewares }} + - name: {{ . }} + namespace: traefik + {{- end }} + {{- end }} + {{- end }} + + - match: Host(`{{ .Values.ingress.host | default (printf "%s.%s" "gohoarder" .Values.global.domain) }}`) && PathPrefix(`/go/`) + kind: Rule + priority: 100 + services: + - name: {{ include "gohoarder.fullname" . }}-frontend + port: {{ .Values.frontend.service.port }} + middlewares: + - name: {{ include "gohoarder.fullname" . }}-strip-encoded-slash + namespace: {{ .Release.Namespace }} + {{- if .Values.ingress.traefik }} + {{- if .Values.ingress.traefik.middlewares }} + {{- range .Values.ingress.traefik.middlewares }} + - name: {{ . }} + namespace: traefik + {{- end }} + {{- end }} + {{- end }} + + # All other routes (frontend, API, etc.) with lower priority + - match: Host(`{{ .Values.ingress.host | default (printf "%s.%s" "gohoarder" .Values.global.domain) }}`) + kind: Rule + priority: 50 + services: + - name: {{ include "gohoarder.fullname" . }}-frontend + port: {{ .Values.frontend.service.port }} + {{- if .Values.ingress.traefik }} + {{- if .Values.ingress.traefik.middlewares }} + middlewares: + {{- range .Values.ingress.traefik.middlewares }} + - name: {{ . }} + namespace: traefik + {{- end }} + {{- end }} + {{- end }} + + {{- if .Values.ingress.tls.enabled }} + tls: + secretName: {{ .Values.ingress.tls.secretName }} + {{- end }} + +--- +# Middleware to handle encoded slashes in package paths +# Note: This middleware attempts to work around Traefik's encoded slash limitation +# but may not fully resolve the issue due to Go stdlib constraints +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: {{ include "gohoarder.fullname" . }}-strip-encoded-slash + labels: + {{- include "gohoarder.labels" . | nindent 4 }} +spec: + # Use headers to pass original path information + # The backend can reconstruct the original URL from these headers + headers: + customRequestHeaders: + X-Original-URI: "{{ .Request.URL.Path }}" + X-Forwarded-Path: "{{ .Request.URL.Path }}" + +--- +# ServersTransport configuration for backend communication +# This ensures the backend connection doesn't have additional restrictions +apiVersion: traefik.io/v1alpha1 +kind: ServersTransport +metadata: + name: {{ include "gohoarder.fullname" . }}-transport + labels: + {{- include "gohoarder.labels" . | nindent 4 }} +spec: + insecureSkipVerify: false + {{- if .Values.ingress.traefik }} + {{- if .Values.ingress.traefik.transport }} + {{- with .Values.ingress.traefik.transport }} + serverName: {{ .serverName | default "" }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/gohoarder/values.yaml b/charts/gohoarder/values.yaml index 4a49d4c..5c07fd9 100644 --- a/charts/gohoarder/values.yaml +++ b/charts/gohoarder/values.yaml @@ -51,17 +51,17 @@ image: server: repository: ghcr.io/lukaszraczylo/gohoarder-server pullPolicy: IfNotPresent - tag: "0.1.147" + tag: "0.1.148" frontend: repository: ghcr.io/lukaszraczylo/gohoarder-frontend pullPolicy: IfNotPresent - tag: "0.1.147" + tag: "0.1.148" scanner: repository: ghcr.io/lukaszraczylo/gohoarder-scanner pullPolicy: IfNotPresent - tag: "0.1.147" + tag: "0.1.148" # Service Account serviceAccount: @@ -358,7 +358,7 @@ migration: image: repository: ghcr.io/lukaszraczylo/gohoarder-migrate pullPolicy: IfNotPresent - tag: "0.1.147" + tag: "0.1.148" # Migration settings logLevel: "info" # debug, info, warn, error @@ -514,6 +514,16 @@ ingress: enabled: false secretName: "gohoarder-tls" + # Traefik-specific configuration (when className: "traefik") + # Used by IngressRoute template for advanced routing + traefik: + # Middleware references (from traefik namespace) + # Example: ["default-chain", "rate-limit"] + middlewares: [] + # ServersTransport configuration + transport: + serverName: "" + # Autoscaling configuration autoscaling: enabled: false diff --git a/charts/packages/gohoarder-0.1.148.tgz b/charts/packages/gohoarder-0.1.148.tgz new file mode 100644 index 0000000000000000000000000000000000000000..6abb36dded6ab1ea76fc9a74db06c610430969a6 GIT binary patch literal 19035 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 uCJpROJv!a<5eZCYnjI