diff --git a/README.md b/README.md index 9b12f8d..3612d71 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,6 @@ Welcome to the Helm repositories index! Explore the available charts below: |------------------|---------------------------------------------------|-------------------------------| | **klogs-viewer** | [View Docs](./charts/klogs-viewer/README.md) | KLogs Viewer is a lightweight, web-based application that allows you to view and download Kubernetes pod logs directly in your browser. Designed for developers and operators who need quick access to container logs without using the command line. | | **kpods-monitor** | [View Docs](./charts/kpods-monitor/README.md) | KPods Monitor is a real-time monitoring tool for Kubernetes pods. It provides a user-friendly interface to view pod status, resource usage, and events. | - +| **release-tracker** | [View Docs](./charts/release-tracker/README.md) | Release Tracker is a comprehensive Kubernetes application that tracks container image deployments across namespaces, providing a modern web interface to monitor and visualize release history with real-time updates. | **Stay tuned for more charts!** diff --git a/charts/klogs-viewer/Chart.yaml b/charts/klogs-viewer/Chart.yaml index 2046420..ed4be04 100644 --- a/charts/klogs-viewer/Chart.yaml +++ b/charts/klogs-viewer/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.12 +version: 0.1.13 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/charts/klogs-viewer/templates/clusterrole.yaml b/charts/klogs-viewer/templates/clusterrole.yaml index c2f0c9d..4a796f7 100644 --- a/charts/klogs-viewer/templates/clusterrole.yaml +++ b/charts/klogs-viewer/templates/clusterrole.yaml @@ -2,7 +2,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: {{ default "klogs-viewer" .Values.rbac.clusterRole.name }} + name: {{ include "chart.fullname" . }} labels: {{- include "chart.labels" . | nindent 4 }} rules: @@ -14,15 +14,15 @@ rules: apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: - name: {{ default "klogs-viewer" .Values.rbac.clusterRole.name }}-{{ include "chart.namespace" . }} + name: {{ include "chart.fullname" . }}-{{ include "chart.namespace" . }} labels: {{- include "chart.labels" . | nindent 4 }} subjects: - kind: ServiceAccount - name: {{ default "klogs-viewer" .Values.serviceAccount.name }} + name: {{ include "chart.serviceAccountName" . }} namespace: {{ include "chart.namespace" . }} roleRef: kind: ClusterRole - name: {{ default "klogs-viewer" .Values.rbac.clusterRole.name }} + name: {{ include "chart.fullname" . }} apiGroup: rbac.authorization.k8s.io {{- end }} \ No newline at end of file diff --git a/charts/klogs-viewer/templates/deployment.yaml b/charts/klogs-viewer/templates/deployment.yaml index 0d1c258..0835985 100644 --- a/charts/klogs-viewer/templates/deployment.yaml +++ b/charts/klogs-viewer/templates/deployment.yaml @@ -1,7 +1,7 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: klogs-viewer + name: {{ include "chart.fullname" . }} namespace: {{ include "chart.namespace" . }} labels: {{- include "chart.labels" . | nindent 4 }} @@ -55,7 +55,7 @@ spec: - name: TOKEN valueFrom: secretKeyRef: - name: klogs-viewer + name: {{ include "chart.fullname" . }} key: token {{- end }} {{- if .Values.application.replaceLabel }} diff --git a/charts/klogs-viewer/templates/ingress.yaml b/charts/klogs-viewer/templates/ingress.yaml index dbeec0f..fde14b6 100644 --- a/charts/klogs-viewer/templates/ingress.yaml +++ b/charts/klogs-viewer/templates/ingress.yaml @@ -1,8 +1,10 @@ {{- if .Values.ingress.enabled -}} +{{- $fullName := include "chart.fullname" . -}} +{{- $svcPort := .Values.service.port -}} apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - name: klogs-viewer + name: {{ $fullName }} namespace: {{ include "chart.namespace" . }} labels: {{- include "chart.labels" . | nindent 4 }} @@ -34,9 +36,9 @@ spec: pathType: {{ .pathType }} backend: service: - name: {{ default "klogs-viewer" $.Values.service.name }} + name: {{ $fullName }} port: - number: {{ $.Values.service.port }} + number: {{ $svcPort }} {{- end }} {{- end }} {{- end }} diff --git a/charts/klogs-viewer/templates/role.yaml b/charts/klogs-viewer/templates/role.yaml index 866d153..8d72993 100644 --- a/charts/klogs-viewer/templates/role.yaml +++ b/charts/klogs-viewer/templates/role.yaml @@ -2,7 +2,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: {{ default "klogs-viewer" .Values.rbac.role.name }} + name: {{ include "chart.fullname" . }} namespace: {{ include "chart.namespace" . }} labels: {{- include "chart.labels" . | nindent 4 }} @@ -15,16 +15,16 @@ rules: apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: - name: {{ default "klogs-viewer" .Values.rbac.role.name }} + name: {{ include "chart.fullname" . }} namespace: {{ include "chart.namespace" . }} labels: {{- include "chart.labels" . | nindent 4 }} subjects: - kind: ServiceAccount - name: {{ default "klogs-viewer" .Values.serviceAccount.name }} + name: {{ include "chart.serviceAccountName" . }} namespace: {{ include "chart.namespace" . }} roleRef: kind: Role - name: {{ default "klogs-viewer" .Values.rbac.role.name }} + name: {{ include "chart.fullname" . }} apiGroup: rbac.authorization.k8s.io {{- end }} \ No newline at end of file diff --git a/charts/klogs-viewer/templates/secret.yaml b/charts/klogs-viewer/templates/secret.yaml index 8c77433..967c60d 100644 --- a/charts/klogs-viewer/templates/secret.yaml +++ b/charts/klogs-viewer/templates/secret.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Secret metadata: - name: klogs-viewer + name: {{ include "chart.fullname" . }} namespace: {{ include "chart.namespace" . }} labels: {{- include "chart.labels" . | nindent 4 }} diff --git a/charts/klogs-viewer/templates/service.yaml b/charts/klogs-viewer/templates/service.yaml index 111407f..9f6dc16 100644 --- a/charts/klogs-viewer/templates/service.yaml +++ b/charts/klogs-viewer/templates/service.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: Service metadata: - name: {{ default "klogs-viewer" .Values.service.name }} + name: {{ include "chart.fullname" . }} namespace: {{ include "chart.namespace" . }} labels: {{- include "chart.labels" . | nindent 4 }} diff --git a/charts/klogs-viewer/templates/serviceaccount.yaml b/charts/klogs-viewer/templates/serviceaccount.yaml index ac5cd45..88139a8 100644 --- a/charts/klogs-viewer/templates/serviceaccount.yaml +++ b/charts/klogs-viewer/templates/serviceaccount.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: ServiceAccount metadata: - name: {{ default "klogs-viewer" .Values.serviceAccount.name }} + name: {{ include "chart.serviceAccountName" . }} namespace: {{ include "chart.namespace" . }} labels: {{- include "chart.labels" . | nindent 4 }} diff --git a/charts/kpods-monitor/Chart.yaml b/charts/kpods-monitor/Chart.yaml index fbcb0d5..a7cb989 100644 --- a/charts/kpods-monitor/Chart.yaml +++ b/charts/kpods-monitor/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: kpods-monitor description: A Helm chart for Kubernetes Pod Monitor type: application -version: 0.1.2 -appVersion: "0.1.2" +version: 0.2.5 +appVersion: "0.2.2" keywords: - kubernetes - monitoring diff --git a/charts/kpods-monitor/README.md b/charts/kpods-monitor/README.md index 7d6ac58..31a26bf 100644 --- a/charts/kpods-monitor/README.md +++ b/charts/kpods-monitor/README.md @@ -35,6 +35,7 @@ The following table lists the configurable parameters of the Kubernetes Pod Moni | `imagePullSecrets` | Image pull secrets | `[]` | | `nameOverride` | Override the name of the chart | `""` | | `fullnameOverride` | Override the full name of the chart | `""` | +| `namespace` | Namespace for the application | `""` | | `serviceAccount.create` | Create a service account | `true` | | `serviceAccount.name` | The name of the service account | `""` | | `podAnnotations` | Annotations for the pods | `{}` | @@ -54,7 +55,6 @@ The following table lists the configurable parameters of the Kubernetes Pod Moni | Parameter | Description | Default | |--------------------------------------------|-------------------------------------------------|--------------------------------| | `config.general.name` | Dashboard name | `"Kubernetes Pod Monitor"` | -| `config.general.refreshInterval` | Data refresh interval in seconds | `30` | | `config.general.port` | Application port | `8080` | | `config.general.debug` | Enable debug logging | `false` | | `config.general.basePath` | Base path for serving the application | `""` | @@ -67,7 +67,6 @@ The following table lists the configurable parameters of the Kubernetes Pod Moni | `config.cluster.kubeConfigPath` | Path to kubeconfig file | `""` | | `config.applications` | Applications to monitor | See `values.yaml` | - ## Example: Monitoring Custom Applications To monitor your own applications, modify the `config.applications` section in your `values.yaml`: diff --git a/charts/kpods-monitor/templates/_helpers.tpl b/charts/kpods-monitor/templates/_helpers.tpl index 0ae4b1c..c1a801b 100644 --- a/charts/kpods-monitor/templates/_helpers.tpl +++ b/charts/kpods-monitor/templates/_helpers.tpl @@ -60,3 +60,15 @@ Create the name of the service account to use {{- default "default" .Values.serviceAccount.name }} {{- end }} {{- end }} + + +{{/* +Get the namespace for resources +*/}} +{{- define "chart.namespace" -}} +{{- if .Values.namespace }} +{{- .Values.namespace }} +{{- else }} +{{- .Release.Namespace }} +{{- end }} +{{- end }} diff --git a/charts/kpods-monitor/templates/configmap.yaml b/charts/kpods-monitor/templates/configmap.yaml index daf22dc..b74b301 100644 --- a/charts/kpods-monitor/templates/configmap.yaml +++ b/charts/kpods-monitor/templates/configmap.yaml @@ -2,13 +2,13 @@ apiVersion: v1 kind: ConfigMap metadata: name: {{ include "kpods-monitor.fullname" . }}-config + namespace: {{ include "chart.namespace" . }} labels: {{- include "kpods-monitor.labels" . | nindent 4 }} data: config.yaml: | general: name: {{ .Values.config.general.name | quote }} - refreshInterval: {{ .Values.config.general.refreshInterval }} port: {{ .Values.config.general.port }} debug: {{ .Values.config.general.debug }} basePath: {{ default "" .Values.config.general.basePath }} diff --git a/charts/kpods-monitor/templates/deployment.yaml b/charts/kpods-monitor/templates/deployment.yaml index 03a7e10..2b9673f 100644 --- a/charts/kpods-monitor/templates/deployment.yaml +++ b/charts/kpods-monitor/templates/deployment.yaml @@ -2,6 +2,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "kpods-monitor.fullname" . }} + namespace: {{ include "chart.namespace" . }} labels: {{- include "kpods-monitor.labels" . | nindent 4 }} spec: diff --git a/charts/kpods-monitor/templates/ingress.yaml b/charts/kpods-monitor/templates/ingress.yaml index 00f785d..b79817a 100644 --- a/charts/kpods-monitor/templates/ingress.yaml +++ b/charts/kpods-monitor/templates/ingress.yaml @@ -5,6 +5,7 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: {{ $fullName }} + namespace: {{ include "chart.namespace" . }} labels: {{- include "kpods-monitor.labels" . | nindent 4 }} {{- with .Values.ingress.annotations }} @@ -22,7 +23,9 @@ spec: {{- range .hosts }} - {{ . | quote }} {{- end }} + {{- if .secretName }} secretName: {{ .secretName }} + {{- end }} {{- end }} {{- end }} rules: diff --git a/charts/kpods-monitor/templates/rbac.yaml b/charts/kpods-monitor/templates/rbac.yaml index ee16c34..134a9f7 100644 --- a/charts/kpods-monitor/templates/rbac.yaml +++ b/charts/kpods-monitor/templates/rbac.yaml @@ -32,5 +32,5 @@ roleRef: subjects: - kind: ServiceAccount name: {{ include "kpods-monitor.serviceAccountName" . }} - namespace: {{ .Release.Namespace }} + namespace: {{ include "chart.namespace" . }} {{- end }} diff --git a/charts/kpods-monitor/templates/service.yaml b/charts/kpods-monitor/templates/service.yaml index d76b4a0..985464c 100644 --- a/charts/kpods-monitor/templates/service.yaml +++ b/charts/kpods-monitor/templates/service.yaml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: name: {{ include "kpods-monitor.fullname" . }} + namespace: {{ include "chart.namespace" . }} labels: {{- include "kpods-monitor.labels" . | nindent 4 }} spec: diff --git a/charts/kpods-monitor/templates/serviceaccount.yaml b/charts/kpods-monitor/templates/serviceaccount.yaml index 5a4fb9b..8e51d82 100644 --- a/charts/kpods-monitor/templates/serviceaccount.yaml +++ b/charts/kpods-monitor/templates/serviceaccount.yaml @@ -3,6 +3,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: {{ include "kpods-monitor.serviceAccountName" . }} + namespace: {{ include "chart.namespace" . }} labels: {{- include "kpods-monitor.labels" . | nindent 4 }} {{- with .Values.serviceAccount.annotations }} diff --git a/charts/kpods-monitor/values.yaml b/charts/kpods-monitor/values.yaml index e97dbac..a15f728 100644 --- a/charts/kpods-monitor/values.yaml +++ b/charts/kpods-monitor/values.yaml @@ -13,6 +13,7 @@ image: imagePullSecrets: [] nameOverride: "" fullnameOverride: "" +namespace: "" serviceAccount: # Specifies whether a service account should be created @@ -76,7 +77,6 @@ affinity: {} config: general: name: "Kubernetes Pod Monitor Dashboard" - refreshInterval: 30 port: 8080 debug: false # Base path for serving the application (e.g., "/monitor") diff --git a/charts/release-tracker/.helmignore b/charts/release-tracker/.helmignore new file mode 100644 index 0000000..bbc7610 --- /dev/null +++ b/charts/release-tracker/.helmignore @@ -0,0 +1,21 @@ +# Exclude common VCS directories +.git/ +.gitignore +.bzr/ +.hg/ +.svn/ + +# IDEs and editors +*.swp +*.tmp +*.bak +.idea/ +.vscode/ + +# OS files +.DS_Store +Thumbs.db + +# Other +*.tgz + diff --git a/charts/release-tracker/Chart.yaml b/charts/release-tracker/Chart.yaml new file mode 100644 index 0000000..6743d26 --- /dev/null +++ b/charts/release-tracker/Chart.yaml @@ -0,0 +1,19 @@ +apiVersion: v2 +name: release-tracker +description: Helm chart for the Release Tracker application +home: https://github.com/your-org/release-tracker +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/helm/icon/color/helm-icon-color.png +type: application +version: 0.1.0 +appVersion: "0.1.0" +keywords: + - kubernetes + - releases + - tracking + - dashboard +sources: + - https://github.com/your-org/release-tracker +maintainers: + - name: Maintainers + email: devnull@example.com + diff --git a/charts/release-tracker/README.md b/charts/release-tracker/README.md new file mode 100644 index 0000000..d7c1e92 --- /dev/null +++ b/charts/release-tracker/README.md @@ -0,0 +1,251 @@ +# Release Tracker Helm Chart + +![Helm Version](https://img.shields.io/badge/helm-v3-blue) + +This Helm chart deploys Release Tracker, a comprehensive Kubernetes application that tracks container image deployments across namespaces, providing a modern web interface to monitor and visualize release history with real-time updates. + +## Features + +- **🔍 Kubernetes Integration**: Monitors Pods, Deployments, StatefulSets, DaemonSets, and ReplicaSets across specified namespaces +- **💾 Data Storage**: SQLite database with automatic deduplication and retention (10 most recent releases per component) +- **🌐 Web Interface**: + - Modern dashboard with hierarchical table view and full-text search + - Timeline page with release history visualization and change indicators + - Badge viewer for generating release status badges + - Base path support for ingress controllers and path-based routing +- **🔗 REST API**: Comprehensive endpoints for triggering collection, retrieving releases, and accessing history +- **🏷️ Release Badges**: SVG badges for README files with API key authentication +- **🔐 Security**: Optional API key authentication for all endpoints +- **🏗️ Master/Slave Architecture**: Support for multi-client, multi-environment deployments +- **📊 Image SHA Tracking**: Tracks both image tags and SHA256 digests for accurate change detection +- **⚡ Real-time Updates**: Live collection and refresh capabilities +- **🛡️ RBAC Ready**: Complete Kubernetes manifests with proper RBAC configuration + +## Quick Start + +### Installation + +Add the Helm repository and install the chart: + +```bash +helm repo add rogosprojects https://rogosprojects.github.io/helm +helm repo update + +# Simple installation with default values +helm install release-tracker rogosprojects/release-tracker + +# Installation with custom values file +helm install release-tracker rogosprojects/release-tracker \ + --namespace observability --create-namespace \ + --values values.yaml +``` + +### Using with the chart source code: + +```bash +# Clone the repository +git clone https://github.com/rogosprojects/helm.git +cd release-tracker/helm-chart + +# Install directly from the chart directory +helm install release-tracker . --namespace observability --create-namespace +``` + +## Configuration + +The following table lists the main configurable parameters of the chart and their default values. + +### Global Parameters + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `replicaCount` | Number of replicas | `1` | +| `image.repository` | Container image repository | `release-tracker` | +| `image.tag` | Container image tag | `latest` | +| `image.pullPolicy` | Container image pull policy | `IfNotPresent` | +| `image.pullSecrets` | List of image pull secrets | `[]` | +| `nameOverride` | Override the name of the chart | `""` | +| `fullnameOverride` | Override the full name of the chart | `""` | +| `serviceAccount.create` | Create a service account | `true` | +| `serviceAccount.name` | The name of the service account | `""` | +| `serviceAccount.annotations` | Annotations for the service account | `{}` | +| `rbac.create` | Create RBAC resources | `true` | +| `podAnnotations` | Annotations for the pods | `{}` | +| `podSecurityContext` | Security context for the pods | See `values.yaml` | +| `securityContext` | Security context for the containers | See `values.yaml` | +| `service.type` | Service type | `ClusterIP` | +| `service.port` | Service port | `80` | +| `ingress.enabled` | Enable ingress | `false` | +| `ingress.className` | Ingress class name | `""` | +| `ingress.annotations` | Ingress annotations | `{}` | +| `ingress.hosts` | Ingress hosts configuration | See `values.yaml` | +| `ingress.tls` | Ingress TLS configuration | `[]` | +| `resources` | CPU/Memory resource requests/limits | See `values.yaml` | +| `nodeSelector` | Node selector | `{}` | +| `tolerations` | Tolerations | `[]` | +| `affinity` | Affinity | `{}` | + +### Application Configuration + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `env.PORT` | Application port | `"8080"` | +| `env.DATABASE_PATH` | Path to SQLite database file | `"/data/releases.db"` | +| `env.NAMESPACES` | Comma-separated namespaces to monitor | `"default"` | +| `env.COLLECTION_INTERVAL` | Minutes between automatic collections | `"60"` | +| `env.IN_CLUSTER` | Use in-cluster Kubernetes configuration | `"true"` | +| `env.API_KEYS` | Comma-separated API keys for authentication | `""` | +| `env.BASE_PATH` | Base path for serving the application | `""` | +| `env.MODE` | Application mode (master or slave) | `"slave"` | +| `env.MASTER_URL` | Master URL for sync (slave mode only) | `""` | +| `env.MASTER_API_KEY` | Master API key for sync (slave mode only) | `""` | +| `env.SYNC_INTERVAL` | Minutes between syncs (slave mode only) | `"5"` | +| `env.CLIENT_NAME` | Client name for multi-client deployments | `"unknown"` | +| `env.ENV_NAME` | Environment name used in badges | `"unknown"` | +| `env.PROXY_URL` | HTTP/HTTPS proxy URL for sync requests | `""` | +| `env.TLS_INSECURE` | Skip TLS certificate verification | `"false"` | +| `extraEnv` | Additional environment variables | `[]` | + +### Persistence Configuration + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `persistence.enabled` | Enable persistent storage | `false` | +| `persistence.size` | Size of the persistent volume | `1Gi` | +| `persistence.storageClassName` | Storage class name | `""` | +| `persistence.accessModes` | Access modes for the persistent volume | `["ReadWriteOnce"]` | + +## Example: Basic Deployment with Persistence + +To deploy Release Tracker with persistent storage and API authentication: + +```yaml +# values.yaml +persistence: + enabled: true + size: 2Gi + storageClassName: "fast-ssd" + +env: + NAMESPACES: "production,staging,development" + COLLECTION_INTERVAL: "30" + API_KEYS: "your-secure-api-key-here" + ENV_NAME: "production" + CLIENT_NAME: "my-company" + +ingress: + enabled: true + className: "nginx" + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + hosts: + - host: releases.example.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: releases-tls + hosts: + - releases.example.com + +resources: + requests: + memory: 256Mi + cpu: 200m + limits: + memory: 1Gi + cpu: 1000m +``` + +## Example: Master/Slave Architecture + +### Master Instance Configuration + +```yaml +# master-values.yaml +env: + MODE: "master" + API_KEYS: "master-api-key,slave-sync-key" + ENV_NAME: "master" + CLIENT_NAME: "central" + +persistence: + enabled: true + size: 5Gi + +ingress: + enabled: true + hosts: + - host: releases-master.example.com +``` + +### Slave Instance Configuration + +```yaml +# slave-values.yaml +env: + MODE: "slave" + MASTER_URL: "https://releases-master.example.com" + MASTER_API_KEY: "slave-sync-key" + CLIENT_NAME: "production-cluster" + ENV_NAME: "production" + SYNC_INTERVAL: "5" + NAMESPACES: "production,monitoring" +``` + +## Badge Usage + +Release Tracker provides SVG badges for displaying current release versions in README files: + +```markdown +![Release Badge](https://releases.example.com/badges/your-api-key/production/unknown/Deployment/my-app/web) +``` + +**Badge URL Format:** +``` +/badges/{api-key}/{client}/{env}/{workload-kind}/{workload-name}/{container} +``` + +**Badge States:** +- 🟢 **Green**: Successfully deployed with version +- 🔴 **Red**: Query error, invalid request, or authentication failure +- ⚪ **Gray**: No deployment found +- 🟡 **Yellow**: Multiple deployments found in different namespaces + +## Security Considerations + +For production deployments, we recommend: + +1. **Enable Authentication**: Set strong API keys via `env.API_KEYS` + ```yaml + env: + API_KEYS: "your-secure-32-char-api-key-here,backup-key-for-rotation" + ``` + +2. **Namespace Restriction**: Limit monitoring to specific namespaces + ```yaml + env: + NAMESPACES: "production,staging" + ``` + +3. **RBAC Configuration**: The chart creates minimal RBAC permissions by default + - ServiceAccount with read-only access to pods, deployments, statefulsets, daemonsets, and replicasets + - Cluster-wide permissions only for the specified namespaces + +4. **Network Security**: + - Enable TLS via Ingress with proper certificates + - Use network policies to restrict access + - Consider using a dedicated namespace for the application + +5. **Resource Limits**: Set appropriate resource limits to prevent resource exhaustion + ```yaml + resources: + limits: + memory: 512Mi + cpu: 500m + ``` + +## License + +This chart is licensed under the MIT License. See the LICENSE file for details. + diff --git a/charts/release-tracker/templates/NOTES.txt b/charts/release-tracker/templates/NOTES.txt new file mode 100644 index 0000000..cdfe7ce --- /dev/null +++ b/charts/release-tracker/templates/NOTES.txt @@ -0,0 +1,11 @@ +Thanks for installing {{ .Chart.Name }}! + +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} + echo http{{ if (index .Values.ingress.tls 0) }}s{{ end }}://{{ (index .Values.ingress.hosts 0).host }} +{{- else }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "release-tracker.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + kubectl port-forward $POD_NAME 8080:8080 --namespace {{ .Release.Namespace }} + echo "Visit http://127.0.0.1:8080 to use your application" +{{- end }} + diff --git a/charts/release-tracker/templates/_helpers.tpl b/charts/release-tracker/templates/_helpers.tpl new file mode 100644 index 0000000..57a46ad --- /dev/null +++ b/charts/release-tracker/templates/_helpers.tpl @@ -0,0 +1,53 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "release-tracker.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "release-tracker.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 -}} + +{{/* +Common labels +*/}} +{{- define "release-tracker.labels" -}} +helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} +app.kubernetes.io/name: {{ include "release-tracker.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/version: {{ .Chart.AppVersion }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "release-tracker.selectorLabels" -}} +app.kubernetes.io/name: {{ include "release-tracker.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Service account name +*/}} +{{- define "release-tracker.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} +{{- default (include "release-tracker.fullname" .) .Values.serviceAccount.name -}} +{{- else -}} +{{- default "default" .Values.serviceAccount.name -}} +{{- end -}} +{{- end -}} + diff --git a/charts/release-tracker/templates/configmap.yaml b/charts/release-tracker/templates/configmap.yaml new file mode 100644 index 0000000..8d919d0 --- /dev/null +++ b/charts/release-tracker/templates/configmap.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "release-tracker.fullname" . }}-config + labels: + {{- include "release-tracker.labels" . | nindent 4 }} +data: + NAMESPACES: {{ .Values.env.NAMESPACES | quote }} + COLLECTION_INTERVAL: {{ .Values.env.COLLECTION_INTERVAL | quote }} + DATABASE_PATH: {{ .Values.env.DATABASE_PATH | quote }} + PORT: {{ .Values.env.PORT | quote }} + IN_CLUSTER: {{ .Values.env.IN_CLUSTER | quote }} + CLIENT_NAME: {{ .Values.env.CLIENT_NAME | quote }} + ENV_NAME: {{ .Values.env.ENV_NAME | quote }} + {{- if .Values.env.API_KEYS }} + API_KEYS: {{ .Values.env.API_KEYS | quote }} + {{- end }} + BASE_PATH: {{ .Values.env.BASE_PATH | quote }} + MODE: {{ .Values.env.MODE | quote }} + {{- if .Values.env.MASTER_URL }} + MASTER_URL: {{ .Values.env.MASTER_URL | quote }} + {{- end }} + {{- if .Values.env.MASTER_API_KEY }} + MASTER_API_KEY: {{ .Values.env.MASTER_API_KEY | quote }} + {{- end }} + SYNC_INTERVAL: {{ .Values.env.SYNC_INTERVAL | quote }} + {{- if .Values.env.PROXY_URL }} + PROXY_URL: {{ .Values.env.PROXY_URL | quote }} + {{- end }} + TLS_INSECURE: {{ .Values.env.TLS_INSECURE | quote }} + diff --git a/charts/release-tracker/templates/deployment.yaml b/charts/release-tracker/templates/deployment.yaml new file mode 100644 index 0000000..bc4534a --- /dev/null +++ b/charts/release-tracker/templates/deployment.yaml @@ -0,0 +1,94 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "release-tracker.fullname" . }} + labels: + {{- include "release-tracker.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + strategy: + type: Recreate + selector: + matchLabels: + {{- include "release-tracker.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "release-tracker.selectorLabels" . | nindent 8 }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if .Values.image.pullSecrets }} + imagePullSecrets: + {{- toYaml .Values.image.pullSecrets | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "release-tracker.serviceAccountName" . }} + {{- if .Values.initContainers.enabled }} + initContainers: + - name: init-db + image: busybox + command: + - /bin/sh + - -c + - | + mkdir -p /data + chown 1000:1000 /data + chmod 755 /data + volumeMounts: + - name: data + mountPath: /data + securityContext: + runAsUser: 0 + {{- end }} + containers: + - name: {{ include "release-tracker.name" . }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: {{ .Values.env.PORT }} + name: http + protocol: TCP + envFrom: + - configMapRef: + name: {{ include "release-tracker.fullname" . }}-config + {{- with .Values.extraEnv }} + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: data + mountPath: /data + resources: + {{- toYaml .Values.resources | nindent 12 }} + livenessProbe: + httpGet: + path: {{ .Values.env.BASE_PATH }}/health + port: {{ .Values.env.PORT }} + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 5 + failureThreshold: 3 + readinessProbe: + httpGet: + path: {{ .Values.env.BASE_PATH }}/health + port: {{ .Values.env.PORT }} + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + volumes: + - name: data + {{- if .Values.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ include "release-tracker.fullname" . }}-data + {{- else }} + emptyDir: {} + {{- end }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + restartPolicy: Always + diff --git a/charts/release-tracker/templates/ingress.yaml b/charts/release-tracker/templates/ingress.yaml new file mode 100644 index 0000000..dc7f6e8 --- /dev/null +++ b/charts/release-tracker/templates/ingress.yaml @@ -0,0 +1,36 @@ +{{- if .Values.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "release-tracker.fullname" . }} + labels: + {{- include "release-tracker.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ include "release-tracker.fullname" $ }} + port: + number: {{ $.Values.service.port }} + {{- end }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- toYaml .Values.ingress.tls | nindent 4 }} + {{- end }} +{{- end }} + diff --git a/charts/release-tracker/templates/pvc.yaml b/charts/release-tracker/templates/pvc.yaml new file mode 100644 index 0000000..37e8d58 --- /dev/null +++ b/charts/release-tracker/templates/pvc.yaml @@ -0,0 +1,17 @@ +{{- if .Values.persistence.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "release-tracker.fullname" . }}-data + labels: + {{- include "release-tracker.labels" . | nindent 4 }} +spec: + accessModes: {{ toYaml .Values.persistence.accessModes | nindent 2 }} + resources: + requests: + storage: {{ .Values.persistence.size }} + {{- if .Values.persistence.storageClassName }} + storageClassName: {{ .Values.persistence.storageClassName }} + {{- end }} +{{- end }} + diff --git a/charts/release-tracker/templates/rbac.yaml b/charts/release-tracker/templates/rbac.yaml new file mode 100644 index 0000000..736fe78 --- /dev/null +++ b/charts/release-tracker/templates/rbac.yaml @@ -0,0 +1,34 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "release-tracker.fullname" . }} + labels: + {{- include "release-tracker.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] + - apiGroups: ["apps"] + resources: ["deployments", "statefulsets", "daemonsets", "replicasets"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["namespaces"] + verbs: ["get", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "release-tracker.fullname" . }} + labels: + {{- include "release-tracker.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "release-tracker.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "release-tracker.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} + diff --git a/charts/release-tracker/templates/service.yaml b/charts/release-tracker/templates/service.yaml new file mode 100644 index 0000000..a1f7a38 --- /dev/null +++ b/charts/release-tracker/templates/service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "release-tracker.fullname" . }} + labels: + {{- include "release-tracker.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: 8080 + protocol: TCP + name: http + selector: + {{- include "release-tracker.selectorLabels" . | nindent 4 }} + diff --git a/charts/release-tracker/templates/serviceaccount.yaml b/charts/release-tracker/templates/serviceaccount.yaml new file mode 100644 index 0000000..fa798fd --- /dev/null +++ b/charts/release-tracker/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "release-tracker.serviceAccountName" . }} + labels: + {{- include "release-tracker.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} + diff --git a/charts/release-tracker/values.yaml b/charts/release-tracker/values.yaml new file mode 100644 index 0000000..30b52e8 --- /dev/null +++ b/charts/release-tracker/values.yaml @@ -0,0 +1,101 @@ +# Default values for release-tracker. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +nameOverride: "" +fullnameOverride: "" + +image: + repository: release-tracker + tag: latest + pullPolicy: IfNotPresent + pullSecrets: [] + # - name: quayio + +serviceAccount: + create: true + name: "" + annotations: {} + +rbac: + create: true + # If you want to restrict to specific namespaces, provide them via env NAMESPACES. + +podAnnotations: {} + +podSecurityContext: + fsGroup: 1000 + +securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + +service: + type: ClusterIP + port: 80 + +ingress: + enabled: false + className: "" + annotations: {} + hosts: + - host: release-tracker.local + paths: + - path: / + pathType: Prefix + tls: [] + +resources: + requests: + memory: 128Mi + cpu: 100m + limits: + memory: 512Mi + cpu: 500m + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +env: + PORT: "8080" + DATABASE_PATH: "/data/releases.db" + NAMESPACES: "default" + COLLECTION_INTERVAL: "60" # Minutes between collections + IN_CLUSTER: "true" + API_KEYS: "" # API_KEYS can be provided here or via secret + BASE_PATH: "" + MODE: "slave" # Options: "master" or "slave" + MASTER_URL: "" # Required if MODE is "slave" + MASTER_API_KEY: "" # Required if MODE is "slave" + SYNC_INTERVAL: "5" # Minutes between syncs (slave mode only) + CLIENT_NAME: "unknown" + ENV_NAME: "unknown" + PROXY_URL: "" # HTTP/HTTPS proxy URL for sync requests (slave mode only) + TLS_INSECURE: "false" # Skip TLS certificate verification for sync requests (slave mode only) + +extraEnv: [] +# - name: LOG_LEVEL +# value: info + +persistence: + enabled: false + # If enabled, a PVC will be created and mounted at /data + size: 1Gi + storageClassName: "" + accessModes: + - ReadWriteOnce + +initContainers: + enabled: true +