mirror of
https://github.com/lukaszraczylo/helm-charts.git
synced 2026-06-09 23:59:58 +00:00
Release gohoarder 0.0.1
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
apiVersion: v2
|
||||
name: gohoarder
|
||||
description: A universal package cache proxy supporting npm, PyPI, and Go modules with security scanning
|
||||
type: application
|
||||
version: 0.0.1
|
||||
appVersion: "0.0.1"
|
||||
keywords:
|
||||
- package-manager
|
||||
- cache
|
||||
- proxy
|
||||
- npm
|
||||
- pypi
|
||||
- go-modules
|
||||
- security
|
||||
- vulnerability-scanning
|
||||
home: https://github.com/lukaszraczylo/gohoarder
|
||||
sources:
|
||||
- https://github.com/lukaszraczylo/gohoarder
|
||||
maintainers:
|
||||
- name: Lukasz Raczylo
|
||||
email: lukasz@raczylo.com
|
||||
icon: https://raw.githubusercontent.com/lukaszraczylo/gohoarder/main/docs/logo.png
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Lukasz Raczylo
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,499 @@
|
||||
# GoHoarder Helm Chart
|
||||
|
||||
A universal package cache proxy supporting npm, PyPI, and Go modules with integrated security scanning.
|
||||
|
||||
## Features
|
||||
|
||||
- **Multi-Registry Support**: Proxy for npm, PyPI, and Go modules
|
||||
- **Security Scanning**: Integrated vulnerability scanning with multiple scanners
|
||||
- **Flexible Storage**: Support for filesystem, S3, and SMB storage backends
|
||||
- **Metadata Storage**: SQLite or PostgreSQL for metadata
|
||||
- **Auto-Configuration**: Generates configuration from Helm values
|
||||
- **Production Ready**: Includes health checks, resource limits, and security contexts
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Kubernetes 1.19+
|
||||
- Helm 3.0+
|
||||
- PV provisioner support in the underlying infrastructure (for persistent storage)
|
||||
|
||||
## Installation
|
||||
|
||||
### Add Helm Repository
|
||||
|
||||
```bash
|
||||
helm repo add gohoarder https://lukaszraczylo.github.io/gohoarder
|
||||
helm repo update
|
||||
```
|
||||
|
||||
### Install Chart
|
||||
|
||||
```bash
|
||||
# Install with default values
|
||||
helm install gohoarder gohoarder/gohoarder
|
||||
|
||||
# Install with custom values
|
||||
helm install gohoarder gohoarder/gohoarder -f values.yaml
|
||||
|
||||
# Install in a specific namespace
|
||||
helm install gohoarder gohoarder/gohoarder -n gohoarder --create-namespace
|
||||
```
|
||||
|
||||
## Quick Start Examples
|
||||
|
||||
### Minimal Installation
|
||||
|
||||
```bash
|
||||
helm install gohoarder gohoarder/gohoarder \
|
||||
--set global.domain=example.com \
|
||||
--set ingress.enabled=true
|
||||
```
|
||||
|
||||
### With Security Scanning
|
||||
|
||||
```bash
|
||||
helm install gohoarder gohoarder/gohoarder \
|
||||
--set security.enabled=true \
|
||||
--set security.scanners.trivy.enabled=true \
|
||||
--set security.scanners.osv.enabled=true
|
||||
```
|
||||
|
||||
### With S3 Storage
|
||||
|
||||
```bash
|
||||
helm install gohoarder gohoarder/gohoarder \
|
||||
--set storage.backend=s3 \
|
||||
--set storage.s3.bucket=my-bucket \
|
||||
--set storage.s3.region=us-east-1 \
|
||||
--set storage.s3.accessKeyId=AKIAIOSFODNN7EXAMPLE \
|
||||
--set storage.s3.secretAccessKey=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
||||
```
|
||||
|
||||
### With Private Container Registry
|
||||
|
||||
If using images from a private registry, create an image pull secret and reference it:
|
||||
|
||||
```bash
|
||||
# Create a Docker registry secret
|
||||
kubectl create secret docker-registry ghcr-secret \
|
||||
--docker-server=ghcr.io \
|
||||
--docker-username=<your-username> \
|
||||
--docker-password=<your-token> \
|
||||
--docker-email=<your-email> \
|
||||
-n gohoarder
|
||||
|
||||
# Install with the secret
|
||||
helm install gohoarder gohoarder/gohoarder \
|
||||
--set global.imagePullSecrets[0].name=ghcr-secret \
|
||||
-n gohoarder
|
||||
```
|
||||
|
||||
Or using a values file to reference existing secrets:
|
||||
|
||||
```yaml
|
||||
global:
|
||||
imagePullSecrets:
|
||||
- name: ghcr-secret
|
||||
- name: dockerhub-secret # Multiple secrets supported
|
||||
```
|
||||
|
||||
**Auto-create secrets** (chart will create them for you):
|
||||
|
||||
```yaml
|
||||
imageCredentials:
|
||||
ghcr-secret:
|
||||
registry: ghcr.io
|
||||
username: myusername
|
||||
password: mytoken
|
||||
email: myemail@example.com
|
||||
|
||||
global:
|
||||
imagePullSecrets:
|
||||
- name: ghcr-secret
|
||||
```
|
||||
|
||||
> **Note**: Storing credentials in values files is less secure than creating secrets manually. Consider using external secret management solutions like Sealed Secrets or External Secrets Operator for production.
|
||||
|
||||
## Configuration Methods
|
||||
|
||||
GoHoarder supports two configuration methods that can be used together:
|
||||
|
||||
### 1. ConfigMap (Default)
|
||||
|
||||
The chart automatically generates a `config.yaml` from Helm values and mounts it as a ConfigMap. This is the default approach and works out of the box.
|
||||
|
||||
### 2. Environment Variables
|
||||
|
||||
You can override any configuration using environment variables with the format `GOHOARDER_<CONFIG_KEY>` where dots are replaced with underscores.
|
||||
|
||||
**Example using values file:**
|
||||
|
||||
```yaml
|
||||
server:
|
||||
env:
|
||||
- name: GOHOARDER_STORAGE_BACKEND
|
||||
value: "s3"
|
||||
- name: GOHOARDER_STORAGE_S3_BUCKET
|
||||
value: "my-bucket"
|
||||
# Reference secrets for sensitive data
|
||||
- name: GOHOARDER_STORAGE_S3_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: aws-credentials
|
||||
key: secret-access-key
|
||||
- name: GOHOARDER_METADATA_POSTGRESQL_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: postgres-secret
|
||||
key: password
|
||||
```
|
||||
|
||||
**Example using command line:**
|
||||
|
||||
```bash
|
||||
helm install gohoarder gohoarder/gohoarder \
|
||||
--set server.env[0].name=GOHOARDER_STORAGE_BACKEND \
|
||||
--set server.env[0].value=s3 \
|
||||
--set server.env[1].name=GOHOARDER_LOGGING_LEVEL \
|
||||
--set server.env[1].value=debug
|
||||
```
|
||||
|
||||
**Benefits of environment variables:**
|
||||
- Better integration with Kubernetes secrets
|
||||
- Override specific values without modifying ConfigMap
|
||||
- Support for secret references (no plain-text passwords)
|
||||
- Compatible with external secret management (External Secrets Operator, Sealed Secrets)
|
||||
|
||||
**Common environment variable mappings:**
|
||||
|
||||
| Config Path | Environment Variable |
|
||||
|-------------|---------------------|
|
||||
| `storage.backend` | `GOHOARDER_STORAGE_BACKEND` |
|
||||
| `storage.s3.bucket` | `GOHOARDER_STORAGE_S3_BUCKET` |
|
||||
| `storage.s3.region` | `GOHOARDER_STORAGE_S3_REGION` |
|
||||
| `storage.s3.access_key_id` | `GOHOARDER_STORAGE_S3_ACCESS_KEY_ID` |
|
||||
| `storage.s3.secret_access_key` | `GOHOARDER_STORAGE_S3_SECRET_ACCESS_KEY` |
|
||||
| `metadata.backend` | `GOHOARDER_METADATA_BACKEND` |
|
||||
| `metadata.postgresql.host` | `GOHOARDER_METADATA_POSTGRESQL_HOST` |
|
||||
| `metadata.postgresql.password` | `GOHOARDER_METADATA_POSTGRESQL_PASSWORD` |
|
||||
| `security.enabled` | `GOHOARDER_SECURITY_ENABLED` |
|
||||
| `security.scanners.trivy.enabled` | `GOHOARDER_SECURITY_SCANNERS_TRIVY_ENABLED` |
|
||||
| `logging.level` | `GOHOARDER_LOGGING_LEVEL` |
|
||||
| `logging.format` | `GOHOARDER_LOGGING_FORMAT` |
|
||||
|
||||
## Configuration Reference
|
||||
|
||||
The following table lists the configurable parameters and their default values.
|
||||
|
||||
### Global Parameters
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------|-------------|---------|
|
||||
| `nameOverride` | Override the name of the chart | `""` |
|
||||
| `fullnameOverride` | Override the full name of the chart | `""` |
|
||||
| `global.domain` | Base domain for the deployment | `gohoarder.local` |
|
||||
| `global.imagePullSecrets` | Image pull secrets (reference existing) | `[]` |
|
||||
| `imageCredentials` | Auto-create image pull secrets from credentials | `{}` |
|
||||
|
||||
### Replica Count
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------|-------------|---------|
|
||||
| `replicaCount.server` | Number of server replicas | `1` |
|
||||
| `replicaCount.frontend` | Number of frontend replicas | `1` |
|
||||
| `replicaCount.scanner` | Number of scanner replicas | `1` |
|
||||
|
||||
### Image Configuration
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------|-------------|---------|
|
||||
| `image.server.repository` | Server image repository | `ghcr.io/lukaszraczylo/gohoarder-server` |
|
||||
| `image.server.tag` | Server image tag | `latest` |
|
||||
| `image.server.pullPolicy` | Server image pull policy | `IfNotPresent` |
|
||||
| `image.frontend.repository` | Frontend image repository | `ghcr.io/lukaszraczylo/gohoarder-frontend` |
|
||||
| `image.frontend.tag` | Frontend image tag | `latest` |
|
||||
| `image.frontend.pullPolicy` | Frontend image pull policy | `IfNotPresent` |
|
||||
| `image.scanner.repository` | Scanner image repository | `ghcr.io/lukaszraczylo/gohoarder-scanner` |
|
||||
| `image.scanner.tag` | Scanner image tag | `latest` |
|
||||
| `image.scanner.pullPolicy` | Scanner image pull policy | `IfNotPresent` |
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------|-------------|---------|
|
||||
| `server.env` | Additional environment variables for server | `[]` |
|
||||
| `frontend.env` | Additional environment variables for frontend | `[]` |
|
||||
| `scanner.env` | Additional environment variables for scanner | `[]` |
|
||||
|
||||
### Storage Configuration
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------|-------------|---------|
|
||||
| `storage.backend` | Storage backend (filesystem, s3, smb) | `filesystem` |
|
||||
| `storage.filesystem.storageClass` | Storage class for PVC | `""` |
|
||||
| `storage.filesystem.size` | Storage size | `100Gi` |
|
||||
| `storage.filesystem.useHostPath` | Use hostPath instead of PVC | `false` |
|
||||
| `storage.filesystem.hostPath` | Host path for storage | `/var/lib/gohoarder` |
|
||||
| `storage.s3.endpoint` | S3 endpoint | `s3.amazonaws.com` |
|
||||
| `storage.s3.bucket` | S3 bucket name | `gohoarder-cache` |
|
||||
| `storage.s3.region` | S3 region | `us-east-1` |
|
||||
|
||||
### Metadata Configuration
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------|-------------|---------|
|
||||
| `metadata.backend` | Metadata backend (sqlite, postgresql) | `sqlite` |
|
||||
| `metadata.sqlite.persistence.enabled` | Enable persistence for SQLite | `true` |
|
||||
| `metadata.sqlite.persistence.size` | SQLite storage size | `10Gi` |
|
||||
| `metadata.postgresql.host` | PostgreSQL host | `localhost` |
|
||||
| `metadata.postgresql.database` | PostgreSQL database | `gohoarder` |
|
||||
|
||||
### Security Configuration
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------|-------------|---------|
|
||||
| `security.enabled` | Enable security scanning | `false` |
|
||||
| `security.blockOnSeverity` | Block packages on severity | `high` |
|
||||
| `security.scanners.trivy.enabled` | Enable Trivy scanner | `false` |
|
||||
| `security.scanners.osv.enabled` | Enable OSV scanner | `false` |
|
||||
| `security.scanners.grype.enabled` | Enable Grype scanner | `false` |
|
||||
|
||||
### Authentication
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------|-------------|---------|
|
||||
| `auth.enabled` | Enable authentication | `true` |
|
||||
| `auth.adminApiKey` | Admin API key (auto-generated if empty) | `""` |
|
||||
| `auth.existingSecret` | Use existing secret for admin key | `""` |
|
||||
|
||||
### Ingress
|
||||
|
||||
| Parameter | Description | Default |
|
||||
|-----------|-------------|---------|
|
||||
| `ingress.enabled` | Enable ingress | `false` |
|
||||
| `ingress.className` | Ingress class name | `nginx` |
|
||||
| `ingress.frontend.enabled` | Enable frontend ingress | `true` |
|
||||
| `ingress.frontend.host` | Frontend hostname | `gohoarder.local` |
|
||||
| `ingress.frontend.tls.enabled` | Enable TLS for frontend | `false` |
|
||||
|
||||
## High Availability & Scaling
|
||||
|
||||
### Running Multiple Server Replicas
|
||||
|
||||
GoHoarder can run with multiple server replicas for high availability and load distribution, but the configuration must be set correctly to avoid data inconsistency.
|
||||
|
||||
#### ✅ Compatible Configurations (Safe for Multiple Replicas)
|
||||
|
||||
**Storage:**
|
||||
- ✅ **S3** - Fully compatible, recommended for production HA setups
|
||||
- ✅ **SMB** - Compatible, shared network storage
|
||||
- ✅ **Filesystem with RWX** - Compatible when using ReadWriteMany storage classes
|
||||
- ✅ Examples: Longhorn RWX, NFS, CephFS, GlusterFS, Azure Files
|
||||
- ✅ Uses atomic rename operations for safe concurrent writes
|
||||
- ✅ Packages are static/immutable - perfect for shared storage
|
||||
- ❌ Not compatible with local storage or ReadWriteOnce (RWO) PVCs
|
||||
|
||||
**Metadata:**
|
||||
- ✅ **PostgreSQL** - Fully compatible, handles concurrent writes, recommended for HA
|
||||
- ⚠️ **SQLite** - Limited compatibility:
|
||||
- Uses WAL mode which supports concurrent reads
|
||||
- Multiple writers can cause lock contention
|
||||
- Works but may have performance issues under high concurrency
|
||||
- Only if using shared storage (NFS, etc.)
|
||||
|
||||
#### 📋 Recommended HA Configurations
|
||||
|
||||
**Option 1: Cloud Storage (S3)**
|
||||
|
||||
Best for cloud deployments, object storage:
|
||||
|
||||
```yaml
|
||||
replicaCount:
|
||||
server: 3
|
||||
|
||||
storage:
|
||||
backend: s3
|
||||
s3:
|
||||
endpoint: s3.amazonaws.com
|
||||
region: us-east-1
|
||||
bucket: gohoarder-cache
|
||||
|
||||
metadata:
|
||||
backend: postgresql
|
||||
postgresql:
|
||||
host: postgres.database.svc.cluster.local
|
||||
database: gohoarder
|
||||
|
||||
podDisruptionBudget:
|
||||
enabled: true
|
||||
minAvailable: 1
|
||||
```
|
||||
|
||||
**Option 2: Shared Filesystem (Longhorn/NFS)**
|
||||
|
||||
Best for on-premises or self-hosted Kubernetes:
|
||||
|
||||
```yaml
|
||||
replicaCount:
|
||||
server: 3
|
||||
|
||||
storage:
|
||||
backend: filesystem
|
||||
filesystem:
|
||||
# Use RWX storage class (Longhorn, NFS, CephFS, etc.)
|
||||
storageClass: "longhorn" # or "nfs-client", "cephfs", etc.
|
||||
size: "500Gi"
|
||||
accessMode: "ReadWriteMany" # RWX - Critical for multiple replicas!
|
||||
|
||||
metadata:
|
||||
backend: postgresql # Or SQLite with RWX storage
|
||||
postgresql:
|
||||
host: postgres.database.svc.cluster.local
|
||||
database: gohoarder
|
||||
|
||||
podDisruptionBudget:
|
||||
enabled: true
|
||||
minAvailable: 1
|
||||
```
|
||||
|
||||
**Why Filesystem with RWX Works:**
|
||||
- Packages are immutable once cached (static files)
|
||||
- Filesystem backend uses atomic `rename()` operations
|
||||
- Race condition safe: If two replicas cache same package, one wins
|
||||
- Performance: Local filesystem often faster than object storage for reads
|
||||
|
||||
#### ⚠️ What Won't Work with Multiple Replicas
|
||||
|
||||
**Filesystem storage with local volumes:**
|
||||
```yaml
|
||||
# ❌ DON'T DO THIS with multiple replicas
|
||||
storage:
|
||||
backend: filesystem
|
||||
filesystem:
|
||||
useHostPath: true # Each replica gets different storage
|
||||
```
|
||||
|
||||
**SQLite with local storage:**
|
||||
```yaml
|
||||
# ⚠️ AVOID with multiple replicas
|
||||
metadata:
|
||||
backend: sqlite
|
||||
sqlite:
|
||||
persistence:
|
||||
enabled: true # Each replica gets its own database
|
||||
```
|
||||
|
||||
#### 🔄 How It Works
|
||||
|
||||
**Request Deduplication:**
|
||||
- Single replica: Uses `singleflight` to prevent duplicate upstream fetches
|
||||
- Multiple replicas: Each replica may fetch the same package independently
|
||||
- **Mitigation**: Package metadata in shared database prevents duplicate downloads once one replica completes
|
||||
|
||||
**Cache Consistency:**
|
||||
- Storage backend (S3/SMB) ensures all replicas see the same cached packages
|
||||
- Metadata database ensures consistent package information across replicas
|
||||
- First replica to cache a package wins, others will use the cached version
|
||||
|
||||
**Session Affinity:**
|
||||
- Not required - GoHoarder is stateless
|
||||
- Load balancer can distribute requests randomly
|
||||
|
||||
**Scanner Replicas:**
|
||||
- Scanner can run as a single replica or multiple
|
||||
- If multiple scanners enabled, they share work through the metadata database
|
||||
- Package scans are deduplicated via database state
|
||||
|
||||
#### 🔬 Technical Details: Concurrent Write Safety
|
||||
|
||||
**Filesystem Backend with RWX Storage:**
|
||||
|
||||
The filesystem storage backend uses a **temp-file + atomic rename** pattern:
|
||||
|
||||
```go
|
||||
1. Write package to: /cache/npm/package@1.0.0.tmp
|
||||
2. Calculate checksums (MD5, SHA256)
|
||||
3. Atomic rename: .tmp → /cache/npm/package@1.0.0
|
||||
```
|
||||
|
||||
**Why this is safe for concurrent writes:**
|
||||
- `os.Rename()` is atomic on POSIX filesystems
|
||||
- If two replicas cache the same package simultaneously:
|
||||
- Both write to separate `.tmp` files
|
||||
- Both attempt atomic rename
|
||||
- One succeeds, one gets "file exists" error
|
||||
- Result: Same file content, no corruption
|
||||
|
||||
**Package immutability:**
|
||||
- Packages are versioned and immutable (npm/pypi/go semantics)
|
||||
- Same package@version always has identical content
|
||||
- Concurrent writes produce identical results
|
||||
- No risk of partial/corrupted files
|
||||
|
||||
**Quota tracking:**
|
||||
- Per-process mutex (minor inaccuracy across replicas)
|
||||
- Conservative: May undercount slightly
|
||||
- Not critical for operation
|
||||
|
||||
## Uninstallation
|
||||
|
||||
```bash
|
||||
helm uninstall gohoarder -n gohoarder
|
||||
```
|
||||
|
||||
## Upgrading
|
||||
|
||||
```bash
|
||||
helm upgrade gohoarder gohoarder/gohoarder -f values.yaml
|
||||
```
|
||||
|
||||
## Package Manager Configuration
|
||||
|
||||
After installation, configure your package managers to use GoHoarder:
|
||||
|
||||
### NPM
|
||||
|
||||
```bash
|
||||
npm config set registry http://<gohoarder-url>/npm/
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
```bash
|
||||
export GOPROXY=http://<gohoarder-url>/go,direct
|
||||
```
|
||||
|
||||
### PyPI
|
||||
|
||||
```bash
|
||||
pip config set global.index-url http://<gohoarder-url>/pypi/simple
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Check Pod Status
|
||||
|
||||
```bash
|
||||
kubectl get pods -n gohoarder
|
||||
kubectl logs -n gohoarder <pod-name>
|
||||
```
|
||||
|
||||
### Verify Configuration
|
||||
|
||||
```bash
|
||||
kubectl get configmap -n gohoarder <release-name>-gohoarder-config -o yaml
|
||||
```
|
||||
|
||||
### Get Admin API Key
|
||||
|
||||
```bash
|
||||
kubectl get secret -n gohoarder <release-name>-gohoarder-auth -o jsonpath='{.data.admin-api-key}' | base64 -d
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please visit [GitHub](https://github.com/lukaszraczylo/gohoarder) for more information.
|
||||
|
||||
## License
|
||||
|
||||
See the [LICENSE](https://github.com/lukaszraczylo/gohoarder/blob/main/LICENSE) file.
|
||||
@@ -0,0 +1,70 @@
|
||||
** GoHoarder has been installed! **
|
||||
|
||||
1. Get the application URL by running these commands:
|
||||
{{- if .Values.ingress.enabled }}
|
||||
{{- if .Values.ingress.frontend.enabled }}
|
||||
http{{ if .Values.ingress.frontend.tls.enabled }}s{{ end }}://{{ .Values.ingress.frontend.host | default (printf "%s.%s" "gohoarder" .Values.global.domain) }}
|
||||
{{- end }}
|
||||
{{- else if contains "NodePort" .Values.frontend.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "gohoarder.fullname" . }}-frontend)
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT
|
||||
{{- else if contains "LoadBalancer" .Values.frontend.service.type }}
|
||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "gohoarder.fullname" . }}-frontend'
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "gohoarder.fullname" . }}-frontend --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||
echo http://$SERVICE_IP:{{ .Values.frontend.service.port }}
|
||||
{{- else if contains "ClusterIP" .Values.frontend.service.type }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "gohoarder.name" . }},app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=frontend" -o jsonpath="{.items[0].metadata.name}")
|
||||
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
|
||||
{{- end }}
|
||||
|
||||
2. Admin API Key:
|
||||
{{- if .Values.auth.enabled }}
|
||||
{{- if .Values.auth.existingSecret }}
|
||||
The admin API key is stored in the existing secret: {{ .Values.auth.existingSecret }}
|
||||
|
||||
To retrieve it:
|
||||
kubectl get secret {{ .Values.auth.existingSecret }} -n {{ .Release.Namespace }} -o jsonpath='{.data.{{ .Values.auth.secretKey }}}' | base64 -d
|
||||
{{- else if .Values.auth.adminApiKey }}
|
||||
The admin API key you provided: {{ .Values.auth.adminApiKey }}
|
||||
{{- else }}
|
||||
A random admin API key has been generated. To retrieve it:
|
||||
kubectl get secret {{ include "gohoarder.fullname" . }}-auth -n {{ .Release.Namespace }} -o jsonpath='{.data.{{ .Values.auth.secretKey }}}' | base64 -d
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
Authentication is disabled.
|
||||
{{- end }}
|
||||
|
||||
3. Configuration:
|
||||
- Storage backend: {{ .Values.storage.backend }}
|
||||
- Metadata backend: {{ .Values.metadata.backend }}
|
||||
- Security scanning: {{ if .Values.security.enabled }}enabled{{ else }}disabled{{ end }}
|
||||
{{- if .Values.security.enabled }}
|
||||
- Active scanners:
|
||||
{{- range $scanner, $config := .Values.security.scanners }}
|
||||
{{- if $config.enabled }}
|
||||
* {{ $scanner }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
4. Package Proxies:
|
||||
Configure your package managers to use GoHoarder:
|
||||
|
||||
NPM:
|
||||
npm config set registry http://{{ include "gohoarder.fullname" . }}-server.{{ .Release.Namespace }}.svc.cluster.local/npm/
|
||||
|
||||
Go:
|
||||
export GOPROXY=http://{{ include "gohoarder.fullname" . }}-server.{{ .Release.Namespace }}.svc.cluster.local/go,direct
|
||||
|
||||
PyPI:
|
||||
pip config set global.index-url http://{{ include "gohoarder.fullname" . }}-server.{{ .Release.Namespace }}.svc.cluster.local/pypi/simple
|
||||
|
||||
5. Health Checks:
|
||||
- Server health: http://{{ include "gohoarder.fullname" . }}-server.{{ .Release.Namespace }}.svc.cluster.local/health
|
||||
- Server ready: http://{{ include "gohoarder.fullname" . }}-server.{{ .Release.Namespace }}.svc.cluster.local/health/ready
|
||||
|
||||
For more information, visit: https://github.com/lukaszraczylo/gohoarder
|
||||
@@ -0,0 +1,174 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "gohoarder.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
*/}}
|
||||
{{- define "gohoarder.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "gohoarder.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "gohoarder.labels" -}}
|
||||
helm.sh/chart: {{ include "gohoarder.chart" . }}
|
||||
{{ include "gohoarder.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "gohoarder.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "gohoarder.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Server labels
|
||||
*/}}
|
||||
{{- define "gohoarder.server.labels" -}}
|
||||
{{ include "gohoarder.labels" . }}
|
||||
app.kubernetes.io/component: server
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Server selector labels
|
||||
*/}}
|
||||
{{- define "gohoarder.server.selectorLabels" -}}
|
||||
{{ include "gohoarder.selectorLabels" . }}
|
||||
app.kubernetes.io/component: server
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Frontend labels
|
||||
*/}}
|
||||
{{- define "gohoarder.frontend.labels" -}}
|
||||
{{ include "gohoarder.labels" . }}
|
||||
app.kubernetes.io/component: frontend
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Frontend selector labels
|
||||
*/}}
|
||||
{{- define "gohoarder.frontend.selectorLabels" -}}
|
||||
{{ include "gohoarder.selectorLabels" . }}
|
||||
app.kubernetes.io/component: frontend
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Scanner labels
|
||||
*/}}
|
||||
{{- define "gohoarder.scanner.labels" -}}
|
||||
{{ include "gohoarder.labels" . }}
|
||||
app.kubernetes.io/component: scanner
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Scanner selector labels
|
||||
*/}}
|
||||
{{- define "gohoarder.scanner.selectorLabels" -}}
|
||||
{{ include "gohoarder.selectorLabels" . }}
|
||||
app.kubernetes.io/component: scanner
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "gohoarder.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "gohoarder.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Generate admin API key
|
||||
*/}}
|
||||
{{- define "gohoarder.adminApiKey" -}}
|
||||
{{- if .Values.auth.adminApiKey }}
|
||||
{{- .Values.auth.adminApiKey }}
|
||||
{{- else }}
|
||||
{{- randAlphaNum 32 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Storage volume configuration
|
||||
*/}}
|
||||
{{- define "gohoarder.storageVolume" -}}
|
||||
{{- if eq .Values.storage.backend "filesystem" }}
|
||||
{{- if .Values.storage.filesystem.useHostPath }}
|
||||
- name: storage
|
||||
hostPath:
|
||||
path: {{ .Values.storage.filesystem.hostPath }}
|
||||
type: DirectoryOrCreate
|
||||
{{- else if .Values.storage.filesystem.existingClaim }}
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Values.storage.filesystem.existingClaim }}
|
||||
{{- else }}
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "gohoarder.fullname" . }}-storage
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
- name: storage
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Metadata volume configuration
|
||||
*/}}
|
||||
{{- define "gohoarder.metadataVolume" -}}
|
||||
{{- if and (eq .Values.metadata.backend "sqlite") .Values.metadata.sqlite.persistence.enabled }}
|
||||
{{- if .Values.metadata.sqlite.persistence.existingClaim }}
|
||||
- name: metadata
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Values.metadata.sqlite.persistence.existingClaim }}
|
||||
{{- else }}
|
||||
- name: metadata
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "gohoarder.fullname" . }}-metadata
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
- name: metadata
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Trivy cache volume configuration
|
||||
*/}}
|
||||
{{- define "gohoarder.trivyCacheVolume" -}}
|
||||
{{- if .Values.security.scanners.trivy.enabled }}
|
||||
- name: trivy-cache
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,168 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "gohoarder.fullname" . }}-config
|
||||
labels:
|
||||
{{- include "gohoarder.labels" . | nindent 4 }}
|
||||
data:
|
||||
config.yaml: |
|
||||
server:
|
||||
host: {{ .Values.server.host | quote }}
|
||||
port: {{ .Values.server.port }}
|
||||
read_timeout: {{ .Values.server.readTimeout | quote }}
|
||||
write_timeout: {{ .Values.server.writeTimeout | quote }}
|
||||
idle_timeout: {{ .Values.server.idleTimeout | quote }}
|
||||
tls:
|
||||
enabled: false
|
||||
|
||||
storage:
|
||||
backend: {{ .Values.storage.backend | quote }}
|
||||
{{- if eq .Values.storage.backend "filesystem" }}
|
||||
path: "/var/cache/gohoarder"
|
||||
filesystem:
|
||||
base_path: "/var/cache/gohoarder"
|
||||
{{- else if eq .Values.storage.backend "s3" }}
|
||||
s3:
|
||||
endpoint: {{ .Values.storage.s3.endpoint | quote }}
|
||||
region: {{ .Values.storage.s3.region | quote }}
|
||||
bucket: {{ .Values.storage.s3.bucket | quote }}
|
||||
{{- if .Values.storage.s3.existingSecret }}
|
||||
access_key_id: "${S3_ACCESS_KEY_ID}"
|
||||
secret_access_key: "${S3_SECRET_ACCESS_KEY}"
|
||||
{{- else }}
|
||||
access_key_id: {{ .Values.storage.s3.accessKeyId | quote }}
|
||||
secret_access_key: {{ .Values.storage.s3.secretAccessKey | quote }}
|
||||
{{- end }}
|
||||
use_ssl: {{ .Values.storage.s3.useSSL }}
|
||||
{{- else if eq .Values.storage.backend "smb" }}
|
||||
smb:
|
||||
host: {{ .Values.storage.smb.host | quote }}
|
||||
share: {{ .Values.storage.smb.share | quote }}
|
||||
{{- if .Values.storage.smb.existingSecret }}
|
||||
username: "${SMB_USERNAME}"
|
||||
password: "${SMB_PASSWORD}"
|
||||
{{- else }}
|
||||
username: {{ .Values.storage.smb.username | quote }}
|
||||
password: {{ .Values.storage.smb.password | quote }}
|
||||
{{- end }}
|
||||
domain: {{ .Values.storage.smb.domain | quote }}
|
||||
{{- end }}
|
||||
|
||||
metadata:
|
||||
backend: {{ .Values.metadata.backend | quote }}
|
||||
{{- if eq .Values.metadata.backend "sqlite" }}
|
||||
connection: "file:/var/lib/gohoarder/metadata/gohoarder.db?cache=shared&mode=rwc"
|
||||
sqlite:
|
||||
path: "/var/lib/gohoarder/metadata/gohoarder.db"
|
||||
wal_mode: {{ .Values.metadata.sqlite.walMode }}
|
||||
{{- else if eq .Values.metadata.backend "postgresql" }}
|
||||
postgresql:
|
||||
host: {{ .Values.metadata.postgresql.host | quote }}
|
||||
port: {{ .Values.metadata.postgresql.port }}
|
||||
database: {{ .Values.metadata.postgresql.database | quote }}
|
||||
{{- if .Values.metadata.postgresql.existingSecret }}
|
||||
user: "${POSTGRES_USER}"
|
||||
password: "${POSTGRES_PASSWORD}"
|
||||
{{- else }}
|
||||
user: {{ .Values.metadata.postgresql.username | quote }}
|
||||
password: {{ .Values.metadata.postgresql.password | quote }}
|
||||
{{- end }}
|
||||
ssl_mode: {{ .Values.metadata.postgresql.sslMode | quote }}
|
||||
{{- end }}
|
||||
|
||||
cache:
|
||||
default_ttl: {{ .Values.cache.defaultTTL | quote }}
|
||||
cleanup_interval: {{ .Values.cache.cleanupInterval | quote }}
|
||||
max_size_bytes: {{ .Values.cache.maxSizeBytes }}
|
||||
per_project_quota: {{ .Values.cache.perProjectQuota }}
|
||||
ttl_overrides:
|
||||
{{- range $key, $value := .Values.cache.ttlOverrides }}
|
||||
{{ $key }}: {{ $value | quote }}
|
||||
{{- end }}
|
||||
|
||||
security:
|
||||
enabled: {{ .Values.security.enabled }}
|
||||
block_on_severity: {{ .Values.security.blockOnSeverity | quote }}
|
||||
scan_on_download: {{ .Values.security.scanOnDownload }}
|
||||
rescan_interval: {{ .Values.security.rescanInterval | quote }}
|
||||
update_db_on_startup: {{ .Values.security.updateDbOnStartup }}
|
||||
block_thresholds:
|
||||
critical: {{ .Values.security.blockThresholds.critical }}
|
||||
high: {{ .Values.security.blockThresholds.high }}
|
||||
medium: {{ .Values.security.blockThresholds.medium }}
|
||||
low: {{ .Values.security.blockThresholds.low }}
|
||||
scanners:
|
||||
trivy:
|
||||
enabled: {{ .Values.security.scanners.trivy.enabled }}
|
||||
timeout: {{ .Values.security.scanners.trivy.timeout | quote }}
|
||||
cache_db: {{ .Values.security.scanners.trivy.cacheDb | quote }}
|
||||
osv:
|
||||
enabled: {{ .Values.security.scanners.osv.enabled }}
|
||||
api_url: {{ .Values.security.scanners.osv.apiUrl | quote }}
|
||||
timeout: {{ .Values.security.scanners.osv.timeout | quote }}
|
||||
grype:
|
||||
enabled: {{ .Values.security.scanners.grype.enabled }}
|
||||
timeout: {{ .Values.security.scanners.grype.timeout | quote }}
|
||||
govulncheck:
|
||||
enabled: {{ .Values.security.scanners.govulncheck.enabled }}
|
||||
timeout: {{ .Values.security.scanners.govulncheck.timeout | quote }}
|
||||
npm_audit:
|
||||
enabled: {{ .Values.security.scanners.npmAudit.enabled }}
|
||||
timeout: {{ .Values.security.scanners.npmAudit.timeout | quote }}
|
||||
pip_audit:
|
||||
enabled: {{ .Values.security.scanners.pipAudit.enabled }}
|
||||
timeout: {{ .Values.security.scanners.pipAudit.timeout | quote }}
|
||||
ghsa:
|
||||
enabled: {{ .Values.security.scanners.ghsa.enabled }}
|
||||
timeout: {{ .Values.security.scanners.ghsa.timeout | quote }}
|
||||
{{- if or .Values.security.scanners.ghsa.token .Values.security.scanners.ghsa.existingSecret }}
|
||||
token: "${GHSA_TOKEN}"
|
||||
{{- end }}
|
||||
static:
|
||||
enabled: {{ .Values.security.scanners.static.enabled }}
|
||||
max_package_size: {{ .Values.security.scanners.static.maxPackageSize }}
|
||||
check_checksums: {{ .Values.security.scanners.static.checkChecksums }}
|
||||
block_suspicious: {{ .Values.security.scanners.static.blockSuspicious }}
|
||||
|
||||
auth:
|
||||
enabled: {{ .Values.auth.enabled }}
|
||||
key_expiration: {{ .Values.auth.keyExpiration | quote }}
|
||||
bcrypt_cost: {{ .Values.auth.bcryptCost }}
|
||||
audit_log: {{ .Values.auth.auditLog }}
|
||||
|
||||
network:
|
||||
connect_timeout: {{ .Values.network.connectTimeout | quote }}
|
||||
read_timeout: {{ .Values.network.readTimeout | quote }}
|
||||
write_timeout: {{ .Values.network.writeTimeout | quote }}
|
||||
max_idle_conns: {{ .Values.network.maxIdleConns }}
|
||||
max_conns_per_host: {{ .Values.network.maxConnsPerHost }}
|
||||
rate_limit:
|
||||
per_api_key: {{ .Values.network.rateLimit.perApiKey }}
|
||||
per_ip: {{ .Values.network.rateLimit.perIp }}
|
||||
burst_size: {{ .Values.network.rateLimit.burstSize }}
|
||||
circuit_breaker:
|
||||
threshold: {{ .Values.network.circuitBreaker.threshold }}
|
||||
timeout: {{ .Values.network.circuitBreaker.timeout | quote }}
|
||||
reset_interval: {{ .Values.network.circuitBreaker.resetInterval | quote }}
|
||||
retry:
|
||||
max_attempts: {{ .Values.network.retry.maxAttempts }}
|
||||
initial_backoff: {{ .Values.network.retry.initialBackoff | quote }}
|
||||
max_backoff: {{ .Values.network.retry.maxBackoff | quote }}
|
||||
|
||||
logging:
|
||||
level: {{ .Values.logging.level | quote }}
|
||||
format: {{ .Values.logging.format | quote }}
|
||||
|
||||
handlers:
|
||||
go:
|
||||
enabled: {{ .Values.handlers.go.enabled }}
|
||||
upstream_proxy: {{ .Values.handlers.go.upstreamProxy | quote }}
|
||||
checksum_db: {{ .Values.handlers.go.checksumDb | quote }}
|
||||
verify_checksums: {{ .Values.handlers.go.verifyChecksums }}
|
||||
npm:
|
||||
enabled: {{ .Values.handlers.npm.enabled }}
|
||||
upstream_registry: {{ .Values.handlers.npm.upstreamRegistry | quote }}
|
||||
pypi:
|
||||
enabled: {{ .Values.handlers.pypi.enabled }}
|
||||
upstream_url: {{ .Values.handlers.pypi.upstreamUrl | quote }}
|
||||
simple_api_url: {{ .Values.handlers.pypi.simpleApiUrl | quote }}
|
||||
@@ -0,0 +1,85 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "gohoarder.fullname" . }}-frontend
|
||||
labels:
|
||||
{{- include "gohoarder.frontend.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
replicas: {{ .Values.replicaCount.frontend }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "gohoarder.frontend.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
{{- with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "gohoarder.frontend.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.global.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "gohoarder.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: frontend
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
readOnlyRootFilesystem: false
|
||||
image: "{{ .Values.image.frontend.repository }}:{{ .Values.image.frontend.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.frontend.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
protocol: TCP
|
||||
env:
|
||||
- name: API_BASE_URL
|
||||
value: {{ .Values.frontend.backendUrl | default (printf "http://%s-server:%d" (include "gohoarder.fullname" .) (.Values.server.service.port | int)) | quote }}
|
||||
- name: APP_VERSION
|
||||
value: {{ .Chart.AppVersion | quote }}
|
||||
- name: APP_NAME
|
||||
value: "GoHoarder"
|
||||
{{- with .Values.frontend.env }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
livenessProbe:
|
||||
{{- toYaml .Values.frontend.livenessProbe | nindent 12 }}
|
||||
readinessProbe:
|
||||
{{- toYaml .Values.frontend.readinessProbe | nindent 12 }}
|
||||
resources:
|
||||
{{- toYaml .Values.frontend.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
- name: nginx-cache
|
||||
mountPath: /var/cache/nginx
|
||||
- name: nginx-run
|
||||
mountPath: /var/run
|
||||
volumes:
|
||||
- name: tmp
|
||||
emptyDir: {}
|
||||
- name: nginx-cache
|
||||
emptyDir: {}
|
||||
- name: nginx-run
|
||||
emptyDir: {}
|
||||
{{- with .Values.frontend.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.frontend.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.frontend.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,114 @@
|
||||
{{- if .Values.security.enabled }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "gohoarder.fullname" . }}-scanner
|
||||
labels:
|
||||
{{- include "gohoarder.scanner.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount.scanner }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "gohoarder.scanner.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
|
||||
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "gohoarder.scanner.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.global.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "gohoarder.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
initContainers:
|
||||
- name: init-permissions
|
||||
image: busybox:latest
|
||||
command: ['sh', '-c']
|
||||
args:
|
||||
- |
|
||||
mkdir -p /var/cache/gohoarder /var/lib/gohoarder/metadata /tmp/gohoarder
|
||||
{{- if .Values.security.scanners.trivy.enabled }}
|
||||
mkdir -p {{ .Values.security.scanners.trivy.cacheDb }}
|
||||
chown -R 1000:1000 {{ .Values.security.scanners.trivy.cacheDb }}
|
||||
{{- end }}
|
||||
chown -R 1000:1000 /var/cache/gohoarder /var/lib/gohoarder /tmp/gohoarder
|
||||
chmod 750 /var/cache/gohoarder /var/lib/gohoarder
|
||||
volumeMounts:
|
||||
{{- include "gohoarder.storageVolume" . | nindent 8 }}
|
||||
{{- include "gohoarder.metadataVolume" . | nindent 8 }}
|
||||
{{- include "gohoarder.trivyCacheVolume" . | nindent 8 }}
|
||||
- name: tmp
|
||||
mountPath: /tmp/gohoarder
|
||||
securityContext:
|
||||
runAsUser: 0
|
||||
containers:
|
||||
- name: scanner
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.scanner.repository }}:{{ .Values.image.scanner.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.scanner.pullPolicy }}
|
||||
env:
|
||||
- name: CONFIG_FILE
|
||||
value: /etc/gohoarder/config.yaml
|
||||
{{- if and .Values.security.scanners.ghsa.enabled .Values.security.scanners.ghsa.existingSecret }}
|
||||
- name: GHSA_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.security.scanners.ghsa.existingSecret }}
|
||||
key: token
|
||||
{{- else if and .Values.security.scanners.ghsa.enabled .Values.security.scanners.ghsa.token }}
|
||||
- name: GHSA_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "gohoarder.fullname" . }}-ghsa
|
||||
key: token
|
||||
{{- end }}
|
||||
{{- with .Values.scanner.env }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.scanner.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /etc/gohoarder
|
||||
readOnly: true
|
||||
- name: storage
|
||||
mountPath: /var/cache/gohoarder
|
||||
- name: metadata
|
||||
mountPath: /var/lib/gohoarder/metadata
|
||||
{{- if .Values.security.scanners.trivy.enabled }}
|
||||
- name: trivy-cache
|
||||
mountPath: {{ .Values.security.scanners.trivy.cacheDb }}
|
||||
{{- end }}
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: {{ include "gohoarder.fullname" . }}-config
|
||||
{{- include "gohoarder.storageVolume" . | nindent 6 }}
|
||||
{{- include "gohoarder.metadataVolume" . | nindent 6 }}
|
||||
{{- include "gohoarder.trivyCacheVolume" . | nindent 6 }}
|
||||
- name: tmp
|
||||
emptyDir: {}
|
||||
{{- with .Values.scanner.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.scanner.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.scanner.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,194 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "gohoarder.fullname" . }}-server
|
||||
labels:
|
||||
{{- include "gohoarder.server.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
replicas: {{ .Values.replicaCount.server }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "gohoarder.server.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
|
||||
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "gohoarder.server.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.global.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "gohoarder.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
initContainers:
|
||||
- name: init-permissions
|
||||
image: busybox:latest
|
||||
command: ['sh', '-c']
|
||||
args:
|
||||
- |
|
||||
mkdir -p /var/cache/gohoarder /var/lib/gohoarder/metadata /tmp/gohoarder
|
||||
chown -R 1000:1000 /var/cache/gohoarder /var/lib/gohoarder /tmp/gohoarder
|
||||
chmod 750 /var/cache/gohoarder /var/lib/gohoarder
|
||||
volumeMounts:
|
||||
{{- include "gohoarder.storageVolume" . | nindent 8 }}
|
||||
{{- include "gohoarder.metadataVolume" . | nindent 8 }}
|
||||
- name: tmp
|
||||
mountPath: /tmp/gohoarder
|
||||
securityContext:
|
||||
runAsUser: 0
|
||||
containers:
|
||||
- name: server
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.server.repository }}:{{ .Values.image.server.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.server.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.server.port }}
|
||||
protocol: TCP
|
||||
env:
|
||||
- name: CONFIG_FILE
|
||||
value: /etc/gohoarder/config.yaml
|
||||
{{- if and .Values.auth.enabled .Values.auth.existingSecret }}
|
||||
- name: ADMIN_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.auth.existingSecret }}
|
||||
key: {{ .Values.auth.secretKey }}
|
||||
{{- else if .Values.auth.enabled }}
|
||||
- name: ADMIN_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "gohoarder.fullname" . }}-auth
|
||||
key: {{ .Values.auth.secretKey }}
|
||||
{{- end }}
|
||||
{{- if and (eq .Values.storage.backend "s3") .Values.storage.s3.existingSecret }}
|
||||
- name: S3_ACCESS_KEY_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.storage.s3.existingSecret }}
|
||||
key: access-key-id
|
||||
- name: S3_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.storage.s3.existingSecret }}
|
||||
key: secret-access-key
|
||||
{{- else if and (eq .Values.storage.backend "s3") .Values.storage.s3.accessKeyId }}
|
||||
- name: S3_ACCESS_KEY_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "gohoarder.fullname" . }}-s3
|
||||
key: access-key-id
|
||||
- name: S3_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "gohoarder.fullname" . }}-s3
|
||||
key: secret-access-key
|
||||
{{- end }}
|
||||
{{- if and (eq .Values.storage.backend "smb") .Values.storage.smb.existingSecret }}
|
||||
- name: SMB_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.storage.smb.existingSecret }}
|
||||
key: username
|
||||
- name: SMB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.storage.smb.existingSecret }}
|
||||
key: password
|
||||
{{- else if and (eq .Values.storage.backend "smb") .Values.storage.smb.username }}
|
||||
- name: SMB_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "gohoarder.fullname" . }}-smb
|
||||
key: username
|
||||
- name: SMB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "gohoarder.fullname" . }}-smb
|
||||
key: password
|
||||
{{- end }}
|
||||
{{- if and (eq .Values.metadata.backend "postgresql") .Values.metadata.postgresql.existingSecret }}
|
||||
- name: POSTGRES_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.metadata.postgresql.existingSecret }}
|
||||
key: username
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.metadata.postgresql.existingSecret }}
|
||||
key: password
|
||||
{{- else if and (eq .Values.metadata.backend "postgresql") .Values.metadata.postgresql.username }}
|
||||
- name: POSTGRES_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "gohoarder.fullname" . }}-postgresql
|
||||
key: username
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "gohoarder.fullname" . }}-postgresql
|
||||
key: password
|
||||
{{- end }}
|
||||
{{- if and .Values.security.scanners.ghsa.enabled .Values.security.scanners.ghsa.existingSecret }}
|
||||
- name: GHSA_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.security.scanners.ghsa.existingSecret }}
|
||||
key: token
|
||||
{{- else if and .Values.security.scanners.ghsa.enabled .Values.security.scanners.ghsa.token }}
|
||||
- name: GHSA_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "gohoarder.fullname" . }}-ghsa
|
||||
key: token
|
||||
{{- end }}
|
||||
{{- with .Values.server.env }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
livenessProbe:
|
||||
{{- toYaml .Values.server.livenessProbe | nindent 12 }}
|
||||
readinessProbe:
|
||||
{{- toYaml .Values.server.readinessProbe | nindent 12 }}
|
||||
resources:
|
||||
{{- toYaml .Values.server.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /etc/gohoarder
|
||||
readOnly: true
|
||||
- name: storage
|
||||
mountPath: /var/cache/gohoarder
|
||||
- name: metadata
|
||||
mountPath: /var/lib/gohoarder/metadata
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: {{ include "gohoarder.fullname" . }}-config
|
||||
{{- include "gohoarder.storageVolume" . | nindent 6 }}
|
||||
{{- include "gohoarder.metadataVolume" . | nindent 6 }}
|
||||
- name: tmp
|
||||
emptyDir: {}
|
||||
{{- with .Values.server.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.server.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.server.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,14 @@
|
||||
{{- if .Values.imageCredentials }}
|
||||
{{- range $name, $config := .Values.imageCredentials }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ $name }}
|
||||
labels:
|
||||
{{- include "gohoarder.labels" $ | nindent 4 }}
|
||||
type: kubernetes.io/dockerconfigjson
|
||||
data:
|
||||
.dockerconfigjson: {{ printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" $config.registry $config.username $config.password $config.email (printf "%s:%s" $config.username $config.password | b64enc) | b64enc }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,118 @@
|
||||
{{- if .Values.ingress.enabled -}}
|
||||
{{- if .Values.ingress.frontend.enabled -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "gohoarder.fullname" . }}-frontend
|
||||
labels:
|
||||
{{- include "gohoarder.frontend.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.ingress.className }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.frontend.tls.enabled }}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ .Values.ingress.frontend.host | default (printf "%s.%s" "gohoarder" .Values.global.domain) | quote }}
|
||||
secretName: {{ .Values.ingress.frontend.tls.secretName }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- host: {{ .Values.ingress.frontend.host | default (printf "%s.%s" "gohoarder" .Values.global.domain) | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: /npm
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "gohoarder.fullname" . }}-server
|
||||
port:
|
||||
number: {{ .Values.server.service.port }}
|
||||
- path: /pypi
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "gohoarder.fullname" . }}-server
|
||||
port:
|
||||
number: {{ .Values.server.service.port }}
|
||||
- path: /go
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "gohoarder.fullname" . }}-server
|
||||
port:
|
||||
number: {{ .Values.server.service.port }}
|
||||
- path: /api
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "gohoarder.fullname" . }}-server
|
||||
port:
|
||||
number: {{ .Values.server.service.port }}
|
||||
- path: /ws
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "gohoarder.fullname" . }}-server
|
||||
port:
|
||||
number: {{ .Values.server.service.port }}
|
||||
- path: /health
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "gohoarder.fullname" . }}-server
|
||||
port:
|
||||
number: {{ .Values.server.service.port }}
|
||||
- path: /metrics
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "gohoarder.fullname" . }}-server
|
||||
port:
|
||||
number: {{ .Values.server.service.port }}
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "gohoarder.fullname" . }}-frontend
|
||||
port:
|
||||
number: {{ .Values.frontend.service.port }}
|
||||
{{- end }}
|
||||
---
|
||||
{{- if .Values.ingress.api.enabled }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "gohoarder.fullname" . }}-api
|
||||
labels:
|
||||
{{- include "gohoarder.server.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.ingress.className }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.api.tls.enabled }}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ .Values.ingress.api.host | default (printf "api.%s.%s" "gohoarder" .Values.global.domain) | quote }}
|
||||
secretName: {{ .Values.ingress.api.tls.secretName }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- host: {{ .Values.ingress.api.host | default (printf "api.%s.%s" "gohoarder" .Values.global.domain) | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "gohoarder.fullname" . }}-server
|
||||
port:
|
||||
number: {{ .Values.server.service.port }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,37 @@
|
||||
{{- if and (eq .Values.storage.backend "filesystem") (not .Values.storage.filesystem.useHostPath) (not .Values.storage.filesystem.existingClaim) }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "gohoarder.fullname" . }}-storage
|
||||
labels:
|
||||
{{- include "gohoarder.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: storage
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ .Values.storage.filesystem.accessMode }}
|
||||
{{- if .Values.storage.filesystem.storageClass }}
|
||||
storageClassName: {{ .Values.storage.filesystem.storageClass | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.storage.filesystem.size | quote }}
|
||||
{{- end }}
|
||||
---
|
||||
{{- if and (eq .Values.metadata.backend "sqlite") .Values.metadata.sqlite.persistence.enabled (not .Values.metadata.sqlite.persistence.existingClaim) }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "gohoarder.fullname" . }}-metadata
|
||||
labels:
|
||||
{{- include "gohoarder.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: metadata
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ .Values.metadata.sqlite.persistence.accessMode }}
|
||||
{{- if .Values.metadata.sqlite.persistence.storageClass }}
|
||||
storageClassName: {{ .Values.metadata.sqlite.persistence.storageClass | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.metadata.sqlite.persistence.size | quote }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,66 @@
|
||||
{{- if and .Values.auth.enabled (not .Values.auth.existingSecret) }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "gohoarder.fullname" . }}-auth
|
||||
labels:
|
||||
{{- include "gohoarder.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
data:
|
||||
{{- if .Values.auth.adminApiKey }}
|
||||
{{ .Values.auth.secretKey }}: {{ .Values.auth.adminApiKey | b64enc | quote }}
|
||||
{{- else }}
|
||||
{{ .Values.auth.secretKey }}: {{ include "gohoarder.adminApiKey" . | b64enc | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
---
|
||||
{{- if and (eq .Values.storage.backend "s3") (not .Values.storage.s3.existingSecret) .Values.storage.s3.accessKeyId }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "gohoarder.fullname" . }}-s3
|
||||
labels:
|
||||
{{- include "gohoarder.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
data:
|
||||
access-key-id: {{ .Values.storage.s3.accessKeyId | b64enc | quote }}
|
||||
secret-access-key: {{ .Values.storage.s3.secretAccessKey | b64enc | quote }}
|
||||
{{- end }}
|
||||
---
|
||||
{{- if and (eq .Values.storage.backend "smb") (not .Values.storage.smb.existingSecret) .Values.storage.smb.username }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "gohoarder.fullname" . }}-smb
|
||||
labels:
|
||||
{{- include "gohoarder.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
data:
|
||||
username: {{ .Values.storage.smb.username | b64enc | quote }}
|
||||
password: {{ .Values.storage.smb.password | b64enc | quote }}
|
||||
{{- end }}
|
||||
---
|
||||
{{- if and (eq .Values.metadata.backend "postgresql") (not .Values.metadata.postgresql.existingSecret) .Values.metadata.postgresql.username }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "gohoarder.fullname" . }}-postgresql
|
||||
labels:
|
||||
{{- include "gohoarder.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
data:
|
||||
username: {{ .Values.metadata.postgresql.username | b64enc | quote }}
|
||||
password: {{ .Values.metadata.postgresql.password | b64enc | quote }}
|
||||
{{- end }}
|
||||
---
|
||||
{{- if and .Values.security.scanners.ghsa.enabled (not .Values.security.scanners.ghsa.existingSecret) .Values.security.scanners.ghsa.token }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "gohoarder.fullname" . }}-ghsa
|
||||
labels:
|
||||
{{- include "gohoarder.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
data:
|
||||
token: {{ .Values.security.scanners.ghsa.token | b64enc | quote }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,39 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "gohoarder.fullname" . }}-server
|
||||
labels:
|
||||
{{- include "gohoarder.server.labels" . | nindent 4 }}
|
||||
{{- with .Values.server.service.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ .Values.server.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.server.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "gohoarder.server.selectorLabels" . | nindent 4 }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "gohoarder.fullname" . }}-frontend
|
||||
labels:
|
||||
{{- include "gohoarder.frontend.labels" . | nindent 4 }}
|
||||
{{- with .Values.frontend.service.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ .Values.frontend.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.frontend.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "gohoarder.frontend.selectorLabels" . | nindent 4 }}
|
||||
@@ -0,0 +1,12 @@
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "gohoarder.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "gohoarder.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,475 @@
|
||||
# Default values for gohoarder
|
||||
# This is a YAML-formatted file.
|
||||
# Declare variables to be passed into your templates.
|
||||
|
||||
# Override the name of the chart
|
||||
nameOverride: ""
|
||||
# Override the full name of the chart
|
||||
fullnameOverride: ""
|
||||
|
||||
# Global configuration
|
||||
global:
|
||||
# Base domain for the deployment
|
||||
domain: "gohoarder.local"
|
||||
|
||||
# Image pull secrets for private registries
|
||||
# Reference existing secrets by name:
|
||||
# imagePullSecrets:
|
||||
# - name: ghcr-secret
|
||||
# - name: dockerhub-secret
|
||||
imagePullSecrets: []
|
||||
|
||||
# Auto-create image pull secrets from credentials (optional)
|
||||
# If you want the chart to create the secrets for you, use this instead:
|
||||
# imageCredentials:
|
||||
# ghcr-secret:
|
||||
# registry: ghcr.io
|
||||
# username: myusername
|
||||
# password: mytoken
|
||||
# email: myemail@example.com
|
||||
# dockerhub-secret:
|
||||
# registry: https://index.docker.io/v1/
|
||||
# username: myusername
|
||||
# password: mytoken
|
||||
# email: myemail@example.com
|
||||
# Then reference them in global.imagePullSecrets:
|
||||
# - name: ghcr-secret
|
||||
imageCredentials: {}
|
||||
|
||||
# Deployment replicas
|
||||
# NOTE: When running multiple server replicas (>1):
|
||||
# - Use S3 or SMB for storage.backend (not filesystem with local storage)
|
||||
# - Use PostgreSQL for metadata.backend (SQLite has limited concurrency)
|
||||
# - See "High Availability & Scaling" section in README
|
||||
replicaCount:
|
||||
server: 1
|
||||
frontend: 1
|
||||
scanner: 1
|
||||
|
||||
# Image configuration
|
||||
image:
|
||||
server:
|
||||
repository: ghcr.io/lukaszraczylo/gohoarder-server
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "0.0.1"
|
||||
|
||||
frontend:
|
||||
repository: ghcr.io/lukaszraczylo/gohoarder-frontend
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "0.0.1"
|
||||
|
||||
scanner:
|
||||
repository: ghcr.io/lukaszraczylo/gohoarder-scanner
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "0.0.1"
|
||||
|
||||
# Service Account
|
||||
serviceAccount:
|
||||
create: true
|
||||
annotations: {}
|
||||
name: ""
|
||||
|
||||
# Pod annotations
|
||||
podAnnotations: {}
|
||||
|
||||
# Pod security context
|
||||
podSecurityContext:
|
||||
fsGroup: 1000
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
|
||||
# Container security context
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
readOnlyRootFilesystem: true
|
||||
|
||||
# Server configuration
|
||||
server:
|
||||
host: "0.0.0.0"
|
||||
port: 8080
|
||||
readTimeout: "5m"
|
||||
writeTimeout: "5m"
|
||||
idleTimeout: "2m"
|
||||
|
||||
# Additional environment variables for server container
|
||||
# Use this to override config via environment variables
|
||||
# Format: GOHOARDER_<CONFIG_KEY> (dots replaced with underscores)
|
||||
# Examples:
|
||||
# GOHOARDER_STORAGE_BACKEND: s3
|
||||
# GOHOARDER_METADATA_BACKEND: postgresql
|
||||
# env:
|
||||
# - name: GOHOARDER_STORAGE_BACKEND
|
||||
# value: "s3"
|
||||
# - name: GOHOARDER_STORAGE_S3_BUCKET
|
||||
# value: "my-bucket"
|
||||
# - name: GOHOARDER_METADATA_POSTGRESQL_PASSWORD
|
||||
# valueFrom:
|
||||
# secretKeyRef:
|
||||
# name: postgres-secret
|
||||
# key: password
|
||||
env: []
|
||||
|
||||
# Service configuration
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
annotations: {}
|
||||
|
||||
# Resource limits
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 2Gi
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
|
||||
# Liveness and readiness probes
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: http
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health/ready
|
||||
port: http
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
|
||||
# Node selector
|
||||
nodeSelector: {}
|
||||
|
||||
# Tolerations
|
||||
tolerations: []
|
||||
|
||||
# Affinity
|
||||
affinity: {}
|
||||
|
||||
# Frontend configuration
|
||||
frontend:
|
||||
# Backend URL for API calls
|
||||
backendUrl: "" # Auto-configured if empty
|
||||
|
||||
# Additional environment variables for frontend container
|
||||
# env:
|
||||
# - name: API_BASE_URL
|
||||
# value: "https://api.example.com"
|
||||
env: []
|
||||
|
||||
# Service configuration
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
targetPort: 80
|
||||
annotations: {}
|
||||
|
||||
# Resource limits
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
|
||||
# Liveness and readiness probes
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
|
||||
# Scanner configuration
|
||||
scanner:
|
||||
# Additional environment variables for scanner container
|
||||
# env:
|
||||
# - name: GOHOARDER_SECURITY_SCANNERS_TRIVY_ENABLED
|
||||
# value: "true"
|
||||
env: []
|
||||
|
||||
# Resource limits
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 4Gi
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
|
||||
# Storage configuration
|
||||
storage:
|
||||
# Storage backend: filesystem, s3, smb
|
||||
# For multiple server replicas:
|
||||
# - S3 or SMB (recommended)
|
||||
# - Filesystem with ReadWriteMany (RWX) storage class (Longhorn, NFS, CephFS)
|
||||
# - NOT filesystem with ReadWriteOnce (RWO) or local storage
|
||||
backend: "filesystem"
|
||||
|
||||
# Filesystem storage
|
||||
filesystem:
|
||||
# Storage class for PVC
|
||||
# For multiple replicas: use RWX-capable storage class (longhorn, nfs-client, cephfs, etc.)
|
||||
storageClass: ""
|
||||
# Storage size
|
||||
size: "100Gi"
|
||||
# Access mode:
|
||||
# ReadWriteOnce (RWO) - Single replica only
|
||||
# ReadWriteMany (RWX) - Multiple replicas (requires RWX storage class)
|
||||
accessMode: "ReadWriteOnce"
|
||||
# Use hostPath instead of PVC (for single-node testing only)
|
||||
useHostPath: false
|
||||
hostPath: "/var/lib/gohoarder"
|
||||
# Existing PVC name (if you want to use existing PVC)
|
||||
existingClaim: ""
|
||||
|
||||
# S3 storage
|
||||
s3:
|
||||
endpoint: "s3.amazonaws.com"
|
||||
region: "us-east-1"
|
||||
bucket: "gohoarder-cache"
|
||||
accessKeyId: ""
|
||||
secretAccessKey: ""
|
||||
# Use existing secret for S3 credentials
|
||||
existingSecret: ""
|
||||
useSSL: true
|
||||
|
||||
# SMB storage
|
||||
smb:
|
||||
host: ""
|
||||
share: ""
|
||||
username: ""
|
||||
password: ""
|
||||
domain: ""
|
||||
# Use existing secret for SMB credentials
|
||||
existingSecret: ""
|
||||
|
||||
# Metadata storage configuration
|
||||
metadata:
|
||||
# Backend: sqlite, postgresql
|
||||
# For multiple server replicas: postgresql is recommended (sqlite has concurrency limitations)
|
||||
backend: "sqlite"
|
||||
|
||||
# SQLite configuration
|
||||
sqlite:
|
||||
# Use PVC for SQLite database
|
||||
persistence:
|
||||
enabled: true
|
||||
storageClass: ""
|
||||
size: "10Gi"
|
||||
accessMode: "ReadWriteOnce"
|
||||
existingClaim: ""
|
||||
walMode: true
|
||||
|
||||
# PostgreSQL configuration
|
||||
postgresql:
|
||||
# Use bundled PostgreSQL (sets up postgresql subchart)
|
||||
enabled: false
|
||||
host: "localhost"
|
||||
port: 5432
|
||||
database: "gohoarder"
|
||||
username: "gohoarder"
|
||||
password: ""
|
||||
sslMode: "disable"
|
||||
# Use existing secret for PostgreSQL credentials
|
||||
existingSecret: ""
|
||||
|
||||
# Cache configuration
|
||||
cache:
|
||||
defaultTTL: "168h" # 7 days
|
||||
cleanupInterval: "1h"
|
||||
maxSizeBytes: 536870912000 # 500GB
|
||||
perProjectQuota: 53687091200 # 50GB
|
||||
ttlOverrides:
|
||||
npm: "168h"
|
||||
pip: "168h"
|
||||
go: "168h"
|
||||
|
||||
# Security scanning configuration
|
||||
security:
|
||||
enabled: false
|
||||
blockOnSeverity: "high" # none, low, medium, high, critical
|
||||
scanOnDownload: true
|
||||
rescanInterval: "24h"
|
||||
updateDbOnStartup: false
|
||||
|
||||
blockThresholds:
|
||||
critical: 0
|
||||
high: -1
|
||||
medium: -1
|
||||
low: -1
|
||||
|
||||
scanners:
|
||||
trivy:
|
||||
enabled: false
|
||||
timeout: "5m"
|
||||
cacheDb: "/var/lib/trivy"
|
||||
|
||||
osv:
|
||||
enabled: false
|
||||
apiUrl: "https://api.osv.dev"
|
||||
timeout: "30s"
|
||||
|
||||
grype:
|
||||
enabled: false
|
||||
timeout: "5m"
|
||||
|
||||
govulncheck:
|
||||
enabled: false
|
||||
timeout: "5m"
|
||||
|
||||
npmAudit:
|
||||
enabled: false
|
||||
timeout: "2m"
|
||||
|
||||
pipAudit:
|
||||
enabled: false
|
||||
timeout: "2m"
|
||||
|
||||
ghsa:
|
||||
enabled: false
|
||||
timeout: "30s"
|
||||
# GitHub token for higher rate limits
|
||||
token: ""
|
||||
existingSecret: ""
|
||||
|
||||
static:
|
||||
enabled: true
|
||||
maxPackageSize: 2147483648 # 2GB
|
||||
checkChecksums: true
|
||||
blockSuspicious: false
|
||||
|
||||
# Authentication configuration
|
||||
auth:
|
||||
enabled: true
|
||||
keyExpiration: "0" # Never expire
|
||||
bcryptCost: 10
|
||||
auditLog: true
|
||||
|
||||
# Admin API key - will be auto-generated if not provided
|
||||
adminApiKey: ""
|
||||
# Use existing secret for admin API key
|
||||
existingSecret: ""
|
||||
# Secret key name for admin API key
|
||||
secretKey: "admin-api-key"
|
||||
|
||||
# Network configuration
|
||||
network:
|
||||
connectTimeout: "10s"
|
||||
readTimeout: "5m"
|
||||
writeTimeout: "5m"
|
||||
maxIdleConns: 100
|
||||
maxConnsPerHost: 10
|
||||
|
||||
rateLimit:
|
||||
perApiKey: 1000
|
||||
perIp: 100
|
||||
burstSize: 50
|
||||
|
||||
circuitBreaker:
|
||||
threshold: 5
|
||||
timeout: "30s"
|
||||
resetInterval: "60s"
|
||||
|
||||
retry:
|
||||
maxAttempts: 3
|
||||
initialBackoff: "1s"
|
||||
maxBackoff: "30s"
|
||||
|
||||
# Logging configuration
|
||||
logging:
|
||||
level: "info" # debug, info, warn, error
|
||||
format: "json" # json, pretty
|
||||
|
||||
# Package handlers configuration
|
||||
handlers:
|
||||
go:
|
||||
enabled: true
|
||||
upstreamProxy: "https://proxy.golang.org"
|
||||
checksumDb: "https://sum.golang.org"
|
||||
verifyChecksums: true
|
||||
|
||||
npm:
|
||||
enabled: true
|
||||
upstreamRegistry: "https://registry.npmjs.org"
|
||||
|
||||
pypi:
|
||||
enabled: true
|
||||
upstreamUrl: "https://pypi.org"
|
||||
simpleApiUrl: "https://pypi.org/simple"
|
||||
|
||||
# Ingress configuration
|
||||
ingress:
|
||||
enabled: false
|
||||
className: "nginx"
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "2048m"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
|
||||
|
||||
# Ingress for frontend
|
||||
frontend:
|
||||
enabled: true
|
||||
host: "gohoarder.local"
|
||||
tls:
|
||||
enabled: false
|
||||
secretName: "gohoarder-frontend-tls"
|
||||
|
||||
# Ingress for API (if you want separate ingress)
|
||||
api:
|
||||
enabled: false
|
||||
host: "api.gohoarder.local"
|
||||
tls:
|
||||
enabled: false
|
||||
secretName: "gohoarder-api-tls"
|
||||
|
||||
# Autoscaling configuration
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 10
|
||||
targetCPUUtilizationPercentage: 80
|
||||
targetMemoryUtilizationPercentage: 80
|
||||
|
||||
# Pod Disruption Budget
|
||||
podDisruptionBudget:
|
||||
enabled: false
|
||||
minAvailable: 1
|
||||
|
||||
# Network Policy
|
||||
networkPolicy:
|
||||
enabled: false
|
||||
# Allow external access to server
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector: {}
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8080
|
||||
Binary file not shown.
+29
-1
@@ -1,5 +1,33 @@
|
||||
apiVersion: v1
|
||||
entries:
|
||||
gohoarder:
|
||||
- apiVersion: v2
|
||||
appVersion: 0.0.1
|
||||
created: "2026-01-02T23:23:54.075202022Z"
|
||||
description: A universal package cache proxy supporting npm, PyPI, and Go modules
|
||||
with security scanning
|
||||
digest: 2271641c9d1e9942a02d94fe62b1c49d0835541160bf8abe198a1293ff4b811d
|
||||
home: https://github.com/lukaszraczylo/gohoarder
|
||||
icon: https://raw.githubusercontent.com/lukaszraczylo/gohoarder/main/docs/logo.png
|
||||
keywords:
|
||||
- package-manager
|
||||
- cache
|
||||
- proxy
|
||||
- npm
|
||||
- pypi
|
||||
- go-modules
|
||||
- security
|
||||
- vulnerability-scanning
|
||||
maintainers:
|
||||
- email: lukasz@raczylo.com
|
||||
name: Lukasz Raczylo
|
||||
name: gohoarder
|
||||
sources:
|
||||
- https://github.com/lukaszraczylo/gohoarder
|
||||
type: application
|
||||
urls:
|
||||
- https://github.com/lukaszraczylo/helm-charts/releases/download/gohoarder-0.0.1/gohoarder-0.0.1.tgz
|
||||
version: 0.0.1
|
||||
jobs-manager:
|
||||
- annotations:
|
||||
artifacthub.io/changes: |
|
||||
@@ -1623,4 +1651,4 @@ entries:
|
||||
urls:
|
||||
- https://github.com/lukaszraczylo/helm-charts/releases/download/kubemirror-0.2.8/kubemirror-0.2.8.tgz
|
||||
version: 0.2.8
|
||||
generated: "2025-12-27T03:40:40.629057295Z"
|
||||
generated: "2026-01-02T23:23:54.07379072Z"
|
||||
|
||||
Reference in New Issue
Block a user