From ef93f4a35fe876032dca22331736fe699472506b Mon Sep 17 00:00:00 2001 From: "d.viti" Date: Fri, 3 Oct 2025 01:51:17 +0200 Subject: [PATCH] Add Helm chart for deploying web and API components - Created complete Helm chart with deployments, services, and ingress - Added support for both web frontend and API backend components - Included autoscaling (HPA) for both components - Added pod disruption budgets for high availability - Configured security contexts and best practices - Created helper templates and configuration management - Added production and development value files - Included comprehensive README with installation instructions --- helm/api7ee/.helmignore | 23 ++ helm/api7ee/Chart.yaml | 17 ++ helm/api7ee/README.md | 150 +++++++++++++ helm/api7ee/templates/NOTES.txt | 58 ++++++ helm/api7ee/templates/_helpers.tpl | 62 ++++++ helm/api7ee/templates/configmap.yaml | 10 + helm/api7ee/templates/deployment-api.yaml | 77 +++++++ helm/api7ee/templates/deployment-web.yaml | 77 +++++++ helm/api7ee/templates/hpa-api.yaml | 33 +++ helm/api7ee/templates/hpa-web.yaml | 33 +++ helm/api7ee/templates/ingress.yaml | 47 +++++ .../api7ee/templates/poddisruptionbudget.yaml | 40 ++++ helm/api7ee/templates/secret.yaml | 13 ++ helm/api7ee/templates/service-api.yaml | 23 ++ helm/api7ee/templates/service-web.yaml | 23 ++ helm/api7ee/templates/serviceaccount.yaml | 12 ++ helm/api7ee/values-dev.yaml | 64 ++++++ helm/api7ee/values-production.yaml | 72 +++++++ helm/api7ee/values.yaml | 197 ++++++++++++++++++ 19 files changed, 1031 insertions(+) create mode 100644 helm/api7ee/.helmignore create mode 100644 helm/api7ee/Chart.yaml create mode 100644 helm/api7ee/README.md create mode 100644 helm/api7ee/templates/NOTES.txt create mode 100644 helm/api7ee/templates/_helpers.tpl create mode 100644 helm/api7ee/templates/configmap.yaml create mode 100644 helm/api7ee/templates/deployment-api.yaml create mode 100644 helm/api7ee/templates/deployment-web.yaml create mode 100644 helm/api7ee/templates/hpa-api.yaml create mode 100644 helm/api7ee/templates/hpa-web.yaml create mode 100644 helm/api7ee/templates/ingress.yaml create mode 100644 helm/api7ee/templates/poddisruptionbudget.yaml create mode 100644 helm/api7ee/templates/secret.yaml create mode 100644 helm/api7ee/templates/service-api.yaml create mode 100644 helm/api7ee/templates/service-web.yaml create mode 100644 helm/api7ee/templates/serviceaccount.yaml create mode 100644 helm/api7ee/values-dev.yaml create mode 100644 helm/api7ee/values-production.yaml create mode 100644 helm/api7ee/values.yaml diff --git a/helm/api7ee/.helmignore b/helm/api7ee/.helmignore new file mode 100644 index 0000000..691fa13 --- /dev/null +++ b/helm/api7ee/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ \ No newline at end of file diff --git a/helm/api7ee/Chart.yaml b/helm/api7ee/Chart.yaml new file mode 100644 index 0000000..87ae201 --- /dev/null +++ b/helm/api7ee/Chart.yaml @@ -0,0 +1,17 @@ +apiVersion: v2 +name: api7ee +description: A Helm chart for API7 Enterprise Edition demo application +type: application +version: 0.1.0 +appVersion: "1.0.0" +keywords: + - api7 + - api-gateway + - web + - api +home: https://demo.commandware.it +sources: + - https://git.commandware.com/demos/api7-demo +maintainers: + - name: CommandWare + email: support@commandware.com \ No newline at end of file diff --git a/helm/api7ee/README.md b/helm/api7ee/README.md new file mode 100644 index 0000000..05a4215 --- /dev/null +++ b/helm/api7ee/README.md @@ -0,0 +1,150 @@ +# API7 Enterprise Edition Helm Chart + +This Helm chart deploys the API7 Enterprise Edition demo application, consisting of a Web frontend and API backend service. + +## Prerequisites + +- Kubernetes 1.19+ +- Helm 3.8.0+ +- PV provisioner support in the underlying infrastructure (optional) +- Ingress controller (e.g., NGINX Ingress Controller) + +## Installation + +### Add the Helm repository (if published) + +```bash +helm repo add api7ee https://charts.commandware.com +helm repo update +``` + +### Install the chart + +```bash +# Install with default values +helm install my-api7ee ./helm/api7ee + +# Install in a specific namespace +helm install my-api7ee ./helm/api7ee --namespace api7ee --create-namespace + +# Install with custom values file +helm install my-api7ee ./helm/api7ee -f custom-values.yaml +``` + +## Configuration + +### Key Configuration Options + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `web.enabled` | Enable Web component | `true` | +| `web.replicaCount` | Number of Web replicas | `2` | +| `web.image.repository` | Web image repository | `api7ee/web` | +| `web.image.tag` | Web image tag | `main` | +| `web.service.port` | Web service port | `8000` | +| `api.enabled` | Enable API component | `true` | +| `api.replicaCount` | Number of API replicas | `3` | +| `api.image.repository` | API image repository | `api7ee/api` | +| `api.image.tag` | API image tag | `main` | +| `api.service.port` | API service port | `8080` | +| `ingress.enabled` | Enable ingress | `true` | +| `ingress.hosts[0].host` | Ingress hostname | `demo.commandware.it` | + +### Custom Values Examples + +#### Using a private registry: + +```yaml +global: + imageRegistry: my-registry.example.com + imagePullSecrets: + - name: my-registry-secret +``` + +#### Enabling autoscaling: + +```yaml +web: + autoscaling: + enabled: true + minReplicas: 2 + maxReplicas: 10 + targetCPUUtilizationPercentage: 70 +``` + +#### Custom resource limits: + +```yaml +api: + resources: + limits: + cpu: 2000m + memory: 2Gi + requests: + cpu: 1000m + memory: 1Gi +``` + +## Upgrading + +```bash +# Upgrade to a new version +helm upgrade my-api7ee ./helm/api7ee + +# Upgrade with new values +helm upgrade my-api7ee ./helm/api7ee --set web.replicaCount=3 +``` + +## Uninstallation + +```bash +# Uninstall the release +helm uninstall my-api7ee + +# Uninstall from a specific namespace +helm uninstall my-api7ee --namespace api7ee +``` + +## Monitoring + +If metrics are enabled, the services expose Prometheus-compatible metrics: + +```yaml +metrics: + enabled: true + serviceMonitor: + enabled: true + interval: 30s +``` + +## Troubleshooting + +### Check deployment status: +```bash +kubectl get deployments -l app.kubernetes.io/instance=my-api7ee +``` + +### View logs: +```bash +# Web component logs +kubectl logs -l app.kubernetes.io/instance=my-api7ee,app.kubernetes.io/component=web + +# API component logs +kubectl logs -l app.kubernetes.io/instance=my-api7ee,app.kubernetes.io/component=api +``` + +### Check HPA status: +```bash +kubectl get hpa -l app.kubernetes.io/instance=my-api7ee +``` + +## Security Considerations + +- Pod Security Context is configured to run as non-root user (UID 1000) +- Security Context drops all capabilities and prevents privilege escalation +- Read-only root filesystem is enabled +- Network policies can be enabled to restrict traffic + +## Support + +For issues and questions, please contact support@commandware.com or visit https://git.commandware.com/demos/api7-demo \ No newline at end of file diff --git a/helm/api7ee/templates/NOTES.txt b/helm/api7ee/templates/NOTES.txt new file mode 100644 index 0000000..eeff67d --- /dev/null +++ b/helm/api7ee/templates/NOTES.txt @@ -0,0 +1,58 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.web.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "api7ee.fullname" . }}-web) + 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.web.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 "api7ee.fullname" . }}-web' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "api7ee.fullname" . }}-web --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.web.service.port }} +{{- else if contains "ClusterIP" .Values.web.service.type }} + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward service/{{ include "api7ee.fullname" . }}-web 8080:{{ .Values.web.service.port }} +{{- end }} + +2. Check the deployment status: + kubectl get deployments -n {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "api7ee.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" + +3. View the pods: + kubectl get pods -n {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "api7ee.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" + +4. Check the logs: + # For Web component: + kubectl logs -n {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "api7ee.name" . }},app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=web" + + # For API component: + kubectl logs -n {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "api7ee.name" . }},app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=api" + +5. Scale the deployments: + # Scale Web component: + kubectl scale deployment {{ include "api7ee.fullname" . }}-web -n {{ .Release.Namespace }} --replicas=3 + + # Scale API component: + kubectl scale deployment {{ include "api7ee.fullname" . }}-api -n {{ .Release.Namespace }} --replicas=5 + +{{- if .Values.web.autoscaling.enabled }} + +6. Web Horizontal Pod Autoscaler is enabled: + Min replicas: {{ .Values.web.autoscaling.minReplicas }} + Max replicas: {{ .Values.web.autoscaling.maxReplicas }} + Target CPU: {{ .Values.web.autoscaling.targetCPUUtilizationPercentage }}% + Target Memory: {{ .Values.web.autoscaling.targetMemoryUtilizationPercentage }}% +{{- end }} + +{{- if .Values.api.autoscaling.enabled }} + +7. API Horizontal Pod Autoscaler is enabled: + Min replicas: {{ .Values.api.autoscaling.minReplicas }} + Max replicas: {{ .Values.api.autoscaling.maxReplicas }} + Target CPU: {{ .Values.api.autoscaling.targetCPUUtilizationPercentage }}% + Target Memory: {{ .Values.api.autoscaling.targetMemoryUtilizationPercentage }}% +{{- end }} \ No newline at end of file diff --git a/helm/api7ee/templates/_helpers.tpl b/helm/api7ee/templates/_helpers.tpl new file mode 100644 index 0000000..ac82831 --- /dev/null +++ b/helm/api7ee/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "api7ee.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "api7ee.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 "api7ee.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "api7ee.labels" -}} +helm.sh/chart: {{ include "api7ee.chart" . }} +{{ include "api7ee.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "api7ee.selectorLabels" -}} +app.kubernetes.io/name: {{ include "api7ee.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "api7ee.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "api7ee.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/api7ee/templates/configmap.yaml b/helm/api7ee/templates/configmap.yaml new file mode 100644 index 0000000..4a0eaa5 --- /dev/null +++ b/helm/api7ee/templates/configmap.yaml @@ -0,0 +1,10 @@ +{{- if .Values.configMap.data }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "api7ee.fullname" . }} + labels: + {{- include "api7ee.labels" . | nindent 4 }} +data: + {{- toYaml .Values.configMap.data | nindent 2 }} +{{- end }} \ No newline at end of file diff --git a/helm/api7ee/templates/deployment-api.yaml b/helm/api7ee/templates/deployment-api.yaml new file mode 100644 index 0000000..12ab6fa --- /dev/null +++ b/helm/api7ee/templates/deployment-api.yaml @@ -0,0 +1,77 @@ +{{- if .Values.api.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "api7ee.fullname" . }}-api + labels: + {{- include "api7ee.labels" . | nindent 4 }} + app.kubernetes.io/component: api +spec: + {{- if not .Values.api.autoscaling.enabled }} + replicas: {{ .Values.api.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "api7ee.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: api + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + labels: + {{- include "api7ee.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: api + spec: + {{- with .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "api7ee.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: api + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.global.imageRegistry | default .Values.api.image.registry }}/{{ .Values.api.image.repository }}:{{ .Values.api.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.api.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.api.service.targetPort }} + protocol: TCP + livenessProbe: + {{- toYaml .Values.api.livenessProbe | nindent 12 }} + readinessProbe: + {{- toYaml .Values.api.readinessProbe | nindent 12 }} + resources: + {{- toYaml .Values.api.resources | nindent 12 }} + env: + - name: PORT + value: "{{ .Values.api.service.targetPort }}" + {{- with .Values.api.env }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.configMap.data }} + envFrom: + - configMapRef: + name: {{ include "api7ee.fullname" . }} + {{- end }} + volumeMounts: + - name: tmp + mountPath: /tmp + volumes: + - name: tmp + emptyDir: {} + {{- with .Values.api.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.api.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.api.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/api7ee/templates/deployment-web.yaml b/helm/api7ee/templates/deployment-web.yaml new file mode 100644 index 0000000..bd60682 --- /dev/null +++ b/helm/api7ee/templates/deployment-web.yaml @@ -0,0 +1,77 @@ +{{- if .Values.web.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "api7ee.fullname" . }}-web + labels: + {{- include "api7ee.labels" . | nindent 4 }} + app.kubernetes.io/component: web +spec: + {{- if not .Values.web.autoscaling.enabled }} + replicas: {{ .Values.web.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "api7ee.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: web + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + labels: + {{- include "api7ee.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: web + spec: + {{- with .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "api7ee.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: web + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.global.imageRegistry | default .Values.web.image.registry }}/{{ .Values.web.image.repository }}:{{ .Values.web.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.web.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.web.service.targetPort }} + protocol: TCP + livenessProbe: + {{- toYaml .Values.web.livenessProbe | nindent 12 }} + readinessProbe: + {{- toYaml .Values.web.readinessProbe | nindent 12 }} + resources: + {{- toYaml .Values.web.resources | nindent 12 }} + env: + - name: PORT + value: "{{ .Values.web.service.targetPort }}" + {{- with .Values.web.env }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.configMap.data }} + envFrom: + - configMapRef: + name: {{ include "api7ee.fullname" . }} + {{- end }} + volumeMounts: + - name: tmp + mountPath: /tmp + volumes: + - name: tmp + emptyDir: {} + {{- with .Values.web.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.web.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.web.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/api7ee/templates/hpa-api.yaml b/helm/api7ee/templates/hpa-api.yaml new file mode 100644 index 0000000..8059c5d --- /dev/null +++ b/helm/api7ee/templates/hpa-api.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.api.enabled .Values.api.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "api7ee.fullname" . }}-api + labels: + {{- include "api7ee.labels" . | nindent 4 }} + app.kubernetes.io/component: api +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "api7ee.fullname" . }}-api + minReplicas: {{ .Values.api.autoscaling.minReplicas }} + maxReplicas: {{ .Values.api.autoscaling.maxReplicas }} + metrics: + {{- if .Values.api.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.api.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.api.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.api.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/api7ee/templates/hpa-web.yaml b/helm/api7ee/templates/hpa-web.yaml new file mode 100644 index 0000000..f2c6060 --- /dev/null +++ b/helm/api7ee/templates/hpa-web.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.web.enabled .Values.web.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "api7ee.fullname" . }}-web + labels: + {{- include "api7ee.labels" . | nindent 4 }} + app.kubernetes.io/component: web +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "api7ee.fullname" . }}-web + minReplicas: {{ .Values.web.autoscaling.minReplicas }} + maxReplicas: {{ .Values.web.autoscaling.maxReplicas }} + metrics: + {{- if .Values.web.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.web.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.web.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.web.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/api7ee/templates/ingress.yaml b/helm/api7ee/templates/ingress.yaml new file mode 100644 index 0000000..862c1ec --- /dev/null +++ b/helm/api7ee/templates/ingress.yaml @@ -0,0 +1,47 @@ +{{- if .Values.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "api7ee.fullname" . }} + labels: + {{- include "api7ee.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.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + {{- if eq .service "web" }} + name: {{ include "api7ee.fullname" $ }}-web + port: + number: {{ $.Values.web.service.port }} + {{- else if eq .service "api" }} + name: {{ include "api7ee.fullname" $ }}-api + port: + number: {{ $.Values.api.service.port }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/api7ee/templates/poddisruptionbudget.yaml b/helm/api7ee/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000..7173af2 --- /dev/null +++ b/helm/api7ee/templates/poddisruptionbudget.yaml @@ -0,0 +1,40 @@ +{{- if .Values.podDisruptionBudget.enabled }} +--- +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "api7ee.fullname" . }}-web + labels: + {{- include "api7ee.labels" . | nindent 4 }} + app.kubernetes.io/component: web +spec: + {{- if .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- include "api7ee.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: web +--- +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "api7ee.fullname" . }}-api + labels: + {{- include "api7ee.labels" . | nindent 4 }} + app.kubernetes.io/component: api +spec: + {{- if .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- include "api7ee.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: api +{{- end }} \ No newline at end of file diff --git a/helm/api7ee/templates/secret.yaml b/helm/api7ee/templates/secret.yaml new file mode 100644 index 0000000..1cfe8b0 --- /dev/null +++ b/helm/api7ee/templates/secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.secrets.create }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "api7ee.fullname" . }} + labels: + {{- include "api7ee.labels" . | nindent 4 }} +type: Opaque +data: + {{- range $key, $val := .Values.secrets.data }} + {{ $key }}: {{ $val | b64enc | quote }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/api7ee/templates/service-api.yaml b/helm/api7ee/templates/service-api.yaml new file mode 100644 index 0000000..b0d0a2a --- /dev/null +++ b/helm/api7ee/templates/service-api.yaml @@ -0,0 +1,23 @@ +{{- if .Values.api.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "api7ee.fullname" . }}-api + labels: + {{- include "api7ee.labels" . | nindent 4 }} + app.kubernetes.io/component: api + {{- with .Values.api.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.api.service.type }} + ports: + - port: {{ .Values.api.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "api7ee.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: api +{{- end }} \ No newline at end of file diff --git a/helm/api7ee/templates/service-web.yaml b/helm/api7ee/templates/service-web.yaml new file mode 100644 index 0000000..11b716b --- /dev/null +++ b/helm/api7ee/templates/service-web.yaml @@ -0,0 +1,23 @@ +{{- if .Values.web.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "api7ee.fullname" . }}-web + labels: + {{- include "api7ee.labels" . | nindent 4 }} + app.kubernetes.io/component: web + {{- with .Values.web.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.web.service.type }} + ports: + - port: {{ .Values.web.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "api7ee.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: web +{{- end }} \ No newline at end of file diff --git a/helm/api7ee/templates/serviceaccount.yaml b/helm/api7ee/templates/serviceaccount.yaml new file mode 100644 index 0000000..fa5d2ed --- /dev/null +++ b/helm/api7ee/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "api7ee.serviceAccountName" . }} + labels: + {{- include "api7ee.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/api7ee/values-dev.yaml b/helm/api7ee/values-dev.yaml new file mode 100644 index 0000000..08fa527 --- /dev/null +++ b/helm/api7ee/values-dev.yaml @@ -0,0 +1,64 @@ +# Development environment values for api7ee +# This file contains development-specific configuration overrides + +web: + replicaCount: 1 + + image: + tag: "latest" + pullPolicy: Always + + resources: + limits: + cpu: 250m + memory: 256Mi + requests: + cpu: 100m + memory: 128Mi + + autoscaling: + enabled: false + +api: + replicaCount: 1 + + image: + tag: "latest" + pullPolicy: Always + + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 250m + memory: 256Mi + + autoscaling: + enabled: false + + env: + - name: LOG_LEVEL + value: "debug" + - name: ENVIRONMENT + value: "development" + - name: DEBUG + value: "true" + +ingress: + enabled: false # Use port-forward in dev + +podDisruptionBudget: + enabled: false + +# Disable security features for easier debugging +podSecurityContext: + runAsNonRoot: false + runAsUser: 0 + fsGroup: 0 + +securityContext: + allowPrivilegeEscalation: true + readOnlyRootFilesystem: false + runAsNonRoot: false + runAsUser: 0 \ No newline at end of file diff --git a/helm/api7ee/values-production.yaml b/helm/api7ee/values-production.yaml new file mode 100644 index 0000000..8d8d377 --- /dev/null +++ b/helm/api7ee/values-production.yaml @@ -0,0 +1,72 @@ +# Production environment values for api7ee +# This file contains production-specific configuration overrides + +global: + imageRegistry: "registry.commandware.com" + imagePullSecrets: + - name: registry-secret + +web: + replicaCount: 3 + + image: + tag: "v1.0.0" # Use specific version in production + pullPolicy: Always + + resources: + limits: + cpu: 1000m + memory: 1Gi + requests: + cpu: 500m + memory: 512Mi + + autoscaling: + enabled: true + minReplicas: 3 + maxReplicas: 15 + +api: + replicaCount: 5 + + image: + tag: "v1.0.0" # Use specific version in production + pullPolicy: Always + + resources: + limits: + cpu: 2000m + memory: 2Gi + requests: + cpu: 1000m + memory: 1Gi + + autoscaling: + enabled: true + minReplicas: 5 + maxReplicas: 30 + + env: + - name: LOG_LEVEL + value: "warn" + - name: ENVIRONMENT + value: "production" + +ingress: + annotations: + nginx.ingress.kubernetes.io/rate-limit: "100" + nginx.ingress.kubernetes.io/ssl-protocols: "TLSv1.2 TLSv1.3" + nginx.ingress.kubernetes.io/ssl-ciphers: "HIGH:!aNULL:!MD5" + +podDisruptionBudget: + enabled: true + minAvailable: 2 + +metrics: + enabled: true + serviceMonitor: + enabled: true + interval: 15s + +networkPolicy: + enabled: true \ No newline at end of file diff --git a/helm/api7ee/values.yaml b/helm/api7ee/values.yaml new file mode 100644 index 0000000..0708165 --- /dev/null +++ b/helm/api7ee/values.yaml @@ -0,0 +1,197 @@ +# Default values for api7ee. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +global: + # Global image registry to use for all images + imageRegistry: "" + # Image pull secrets for all images + imagePullSecrets: [] + +# Configuration for the Web component +web: + enabled: true + replicaCount: 2 + + image: + registry: gitea.server_url # Will be replaced with actual Gitea URL + repository: api7ee/web + pullPolicy: IfNotPresent + tag: "main" # Override with specific version + + service: + type: ClusterIP + port: 8000 + targetPort: 8000 + annotations: {} + + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 250m + memory: 256Mi + + autoscaling: + enabled: false + minReplicas: 2 + maxReplicas: 10 + targetCPUUtilizationPercentage: 80 + targetMemoryUtilizationPercentage: 80 + + nodeSelector: {} + tolerations: [] + affinity: {} + + # Additional environment variables + env: [] + + # Liveness and readiness probes + livenessProbe: + httpGet: + path: /docs + port: http + initialDelaySeconds: 30 + periodSeconds: 10 + + readinessProbe: + httpGet: + path: /docs + port: http + initialDelaySeconds: 10 + periodSeconds: 5 + +# Configuration for the API component +api: + enabled: true + replicaCount: 3 + + image: + registry: gitea.server_url # Will be replaced with actual Gitea URL + repository: api7ee/api + pullPolicy: IfNotPresent + tag: "main" # Override with specific version + + service: + type: ClusterIP + port: 8080 + targetPort: 8080 + annotations: {} + + resources: + limits: + cpu: 1000m + memory: 1Gi + requests: + cpu: 500m + memory: 512Mi + + autoscaling: + enabled: true + minReplicas: 3 + maxReplicas: 20 + targetCPUUtilizationPercentage: 70 + targetMemoryUtilizationPercentage: 75 + + nodeSelector: {} + tolerations: [] + affinity: {} + + # Additional environment variables + env: + - name: LOG_LEVEL + value: "info" + + # Liveness and readiness probes + livenessProbe: + httpGet: + path: /health + port: http + initialDelaySeconds: 30 + periodSeconds: 10 + + readinessProbe: + httpGet: + path: /ready + port: http + initialDelaySeconds: 10 + periodSeconds: 5 + +# Ingress configuration +ingress: + enabled: true + className: "nginx" + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / + cert-manager.io/cluster-issuer: "letsencrypt-prod" + + hosts: + - host: demo.commandware.it + paths: + - path: / + pathType: Prefix + service: web # Routes to web service + - path: /api + pathType: Prefix + service: api # Routes to API service + + tls: + - secretName: api7ee-tls + hosts: + - demo.commandware.it + +# ServiceAccount configuration +serviceAccount: + create: true + annotations: {} + name: "" + +# Pod Security Context +podSecurityContext: + runAsNonRoot: true + runAsUser: 1000 + fsGroup: 1000 + +# Security Context for containers +securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + +# Network Policies +networkPolicy: + enabled: false + policyTypes: + - Ingress + - Egress + ingress: [] + egress: [] + +# Pod Disruption Budget +podDisruptionBudget: + enabled: true + minAvailable: 1 + # maxUnavailable: 1 + +# Monitoring and metrics +metrics: + enabled: false + serviceMonitor: + enabled: false + interval: 30s + path: /metrics + labels: {} + +# ConfigMap for shared configuration +configMap: + data: {} + +# Secrets for sensitive data +secrets: + create: false + data: {} \ No newline at end of file