mirror of
https://github.com/lukaszraczylo/helm-charts.git
synced 2026-10-19 06:27:55 +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: [email protected]
|
||||||
|
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: [email protected]
|
||||||
|
|
||||||
|
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: [email protected]
|
||||||
|
# dockerhub-secret:
|
||||||
|
# registry: https://index.docker.io/v1/
|
||||||
|
# username: myusername
|
||||||
|
# password: mytoken
|
||||||
|
# email: [email protected]
|
||||||
|
# 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
|
apiVersion: v1
|
||||||
entries:
|
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: [email protected]
|
||||||
|
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:
|
jobs-manager:
|
||||||
- annotations:
|
- annotations:
|
||||||
artifacthub.io/changes: |
|
artifacthub.io/changes: |
|
||||||
@@ -1623,4 +1651,4 @@ entries:
|
|||||||
urls:
|
urls:
|
||||||
- https://github.com/lukaszraczylo/helm-charts/releases/download/kubemirror-0.2.8/kubemirror-0.2.8.tgz
|
- https://github.com/lukaszraczylo/helm-charts/releases/download/kubemirror-0.2.8/kubemirror-0.2.8.tgz
|
||||||
version: 0.2.8
|
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