diff --git a/app/main.py b/app/main.py index b8965c2..36011ad 100644 --- a/app/main.py +++ b/app/main.py @@ -25,6 +25,76 @@ def coordinates_for_city(city: str): except Exception: t.set_status("500") raise + + +@app.get("/help") +def help_endpoint(): + return { + "api_name": "Open-Meteo Coordinates Service", + "description": "Get geographical coordinates for cities", + "available_cities": ["Tel Aviv", "Beersheba", "Jerusalem", "Szeged"], + "endpoints": [ + { + "path": "/coordinates", + "method": "GET", + "description": "Get coordinates for all available cities", + "example_request": "GET https://open-meteo.dvirlabs.com/coordinates", + "example_response": { + "source": "cache", + "data": { + "Tel Aviv": { + "name": "Tel Aviv", + "latitude": 32.08088, + "longitude": 34.78057, + "country": "Israel" + }, + "Beersheba": { + "name": "Beersheba", + "latitude": 31.25181, + "longitude": 34.7913, + "country": "Israel" + } + } + } + }, + { + "path": "/coordinates/{city}", + "method": "GET", + "description": "Get coordinates for a specific city", + "example_request": "GET https://open-meteo.dvirlabs.com/coordinates/Tel Aviv", + "example_response": { + "source": "cache", + "data": { + "name": "Tel Aviv", + "latitude": 32.08088, + "longitude": 34.78057, + "country": "Israel" + } + } + }, + { + "path": "/healthz", + "method": "GET", + "description": "Health check endpoint", + "example_request": "GET https://open-meteo.dvirlabs.com/healthz", + "example_response": { + "status": "ok" + } + }, + { + "path": "/metrics", + "method": "GET", + "description": "Prometheus metrics endpoint", + "example_request": "GET https://open-meteo.dvirlabs.com/metrics" + } + ], + "usage_examples": { + "curl_all_cities": "curl https://open-meteo.dvirlabs.com/coordinates", + "curl_single_city": "curl https://open-meteo.dvirlabs.com/coordinates/Jerusalem", + "curl_with_spaces": "curl 'https://open-meteo.dvirlabs.com/coordinates/Tel%20Aviv'", + "python": "import requests\nresponse = requests.get('https://open-meteo.dvirlabs.com/coordinates/Jerusalem')\ndata = response.json()" + } + } @app.get("/metrics") def metrics(): diff --git a/open-meteo-service/Chart.yaml b/open-meteo-service/Chart.yaml new file mode 100644 index 0000000..ee0227a --- /dev/null +++ b/open-meteo-service/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: open-meteo-service +description: A FastAPI service that provides city coordinates with Prometheus metrics +type: application +version: 0.1.0 +appVersion: "1.0.0" diff --git a/open-meteo-service/files/grafana/dashboards/open-meteo-service.json b/open-meteo-service/files/grafana/dashboards/open-meteo-service.json new file mode 100644 index 0000000..9fbc437 --- /dev/null +++ b/open-meteo-service/files/grafana/dashboards/open-meteo-service.json @@ -0,0 +1,107 @@ +{ + "uid": "open-meteo-service", + "title": "Open-Meteo Service", + "timezone": "browser", + "schemaVersion": 38, + "version": 1, + "refresh": "10s", + "time": { + "from": "now-15m", + "to": "now" + }, + "panels": [ + { + "id": 1, + "type": "timeseries", + "title": "Request Rate", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { "x": 0, "y": 0, "w": 12, "h": 8 }, + "targets": [ + { + "expr": "sum(rate(http_requests_total[5m])) by (endpoint, method)", + "legendFormat": "{{endpoint}} {{method}}", + "refId": "A" + } + ] + }, + { + "id": 2, + "type": "timeseries", + "title": "Request Duration p95", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { "x": 12, "y": 0, "w": 12, "h": 8 }, + "targets": [ + { + "expr": "histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, endpoint, method))", + "legendFormat": "{{endpoint}} {{method}}", + "refId": "A" + } + ] + }, + { + "id": 3, + "type": "timeseries", + "title": "Cache Hits vs Misses", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { "x": 0, "y": 8, "w": 12, "h": 8 }, + "targets": [ + { + "expr": "rate(coordinates_cache_hits_total[5m])", + "legendFormat": "hits", + "refId": "A" + }, + { + "expr": "rate(coordinates_cache_misses_total[5m])", + "legendFormat": "misses", + "refId": "B" + } + ] + }, + { + "id": 4, + "type": "timeseries", + "title": "Open-Meteo Calls by City", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { "x": 12, "y": 8, "w": 12, "h": 8 }, + "targets": [ + { + "expr": "sum(rate(openmeteo_api_calls_total[5m])) by (city)", + "legendFormat": "{{city}}", + "refId": "A" + } + ] + }, + { + "id": 5, + "type": "timeseries", + "title": "Requests by Status", + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, + "gridPos": { "x": 0, "y": 16, "w": 24, "h": 8 }, + "targets": [ + { + "expr": "sum(rate(http_requests_total[5m])) by (status)", + "legendFormat": "{{status}}", + "refId": "A" + } + ] + } + ], + "templating": { + "list": [] + } +} diff --git a/open-meteo-service/files/grafana/provisioning/dashboards/dashboard.yml b/open-meteo-service/files/grafana/provisioning/dashboards/dashboard.yml new file mode 100644 index 0000000..ea7dac0 --- /dev/null +++ b/open-meteo-service/files/grafana/provisioning/dashboards/dashboard.yml @@ -0,0 +1,10 @@ +apiVersion: 1 + +providers: + - name: default + type: file + disableDeletion: false + editable: true + updateIntervalSeconds: 10 + options: + path: /var/lib/grafana/dashboards diff --git a/open-meteo-service/templates/NOTES.txt b/open-meteo-service/templates/NOTES.txt new file mode 100644 index 0000000..d461a72 --- /dev/null +++ b/open-meteo-service/templates/NOTES.txt @@ -0,0 +1,20 @@ +1. Get the application URL by running these commands: + {{- if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "open-meteo-service.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT/docs + {{- else if contains "LoadBalancer" .Values.service.type }} + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "open-meteo-service.fullname" . }} -o jsonpath="{.status.loadBalancer.ingress[0].ip}") + echo http://$SERVICE_IP:{{ .Values.service.port }}/docs + {{- else }} + kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ include "open-meteo-service.fullname" . }} 8080:{{ .Values.service.port }} + echo http://127.0.0.1:8080/docs + {{- end }} + +2. Prometheus (if enabled): + kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ include "open-meteo-service.prometheusFullname" . }} 9090:{{ .Values.prometheus.service.port }} + echo http://127.0.0.1:9090 + +3. Grafana (if enabled): + kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ include "open-meteo-service.grafanaFullname" . }} 3000:{{ .Values.grafana.service.port }} + echo http://127.0.0.1:3000 ({{ .Values.grafana.adminUser }}/{{ .Values.grafana.adminPassword }}) diff --git a/open-meteo-service/templates/_helpers.tpl b/open-meteo-service/templates/_helpers.tpl new file mode 100644 index 0000000..c071db1 --- /dev/null +++ b/open-meteo-service/templates/_helpers.tpl @@ -0,0 +1,36 @@ +{{- define "open-meteo-service.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "open-meteo-service.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + +{{- define "open-meteo-service.labels" -}} +app.kubernetes.io/name: {{ include "open-meteo-service.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/version: {{ .Chart.AppVersion }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{- define "open-meteo-service.prometheusFullname" -}} +{{- printf "%s-prometheus" (include "open-meteo-service.fullname" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "open-meteo-service.grafanaFullname" -}} +{{- printf "%s-grafana" (include "open-meteo-service.fullname" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Selector labels for API component +*/}} +{{- define "open-meteo-service.selectorLabels" -}} +app.kubernetes.io/name: {{ include "open-meteo-service.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/component: api +{{- end -}} diff --git a/open-meteo-service/templates/app-deployment.yaml b/open-meteo-service/templates/app-deployment.yaml new file mode 100644 index 0000000..2fc4960 --- /dev/null +++ b/open-meteo-service/templates/app-deployment.yaml @@ -0,0 +1,75 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "open-meteo-service.fullname" . }} + annotations: + argocd.argoproj.io/sync-options: Replace=true,Force=true + argocd.argoproj.io/sync-wave: "1" + labels: + {{- include "open-meteo-service.labels" . | nindent 4 }} + app.kubernetes.io/component: api +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "open-meteo-service.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "open-meteo-service.labels" . | nindent 8 }} + app.kubernetes.io/component: api + annotations: + {{- toYaml .Values.podAnnotations | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ include "open-meteo-service.name" . }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.service.port }} + protocol: TCP + env: + - name: CACHE_FILE + value: {{ .Values.env.cacheFile | quote }} + livenessProbe: + httpGet: + path: /healthz + port: http + initialDelaySeconds: 5 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /healthz + port: http + initialDelaySeconds: 5 + periodSeconds: 10 + volumeMounts: + - name: cache-data + mountPath: /data + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumes: + - name: cache-data + {{- if .Values.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ include "open-meteo-service.fullname" . }} + {{- else }} + emptyDir: {} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/open-meteo-service/templates/grafana-configmap.yaml b/open-meteo-service/templates/grafana-configmap.yaml new file mode 100644 index 0000000..ef46b29 --- /dev/null +++ b/open-meteo-service/templates/grafana-configmap.yaml @@ -0,0 +1,24 @@ +{{- if .Values.grafana.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "open-meteo-service.grafanaFullname" . }}-config + labels: + {{- include "open-meteo-service.labels" . | nindent 4 }} + app.kubernetes.io/component: grafana +data: + datasource.yml: |- + apiVersion: 1 + + datasources: + - name: Prometheus + type: prometheus + access: proxy + url: http://{{ include "open-meteo-service.prometheusFullname" . }}:{{ .Values.prometheus.service.port }} + isDefault: true + uid: prometheus + dashboard.yml: |- +{{ .Files.Get "files/grafana/provisioning/dashboards/dashboard.yml" | nindent 4 }} + open-meteo-service.json: |- +{{ .Files.Get "files/grafana/dashboards/open-meteo-service.json" | nindent 4 }} +{{- end }} diff --git a/open-meteo-service/templates/grafana-deployment.yaml b/open-meteo-service/templates/grafana-deployment.yaml new file mode 100644 index 0000000..4b405a0 --- /dev/null +++ b/open-meteo-service/templates/grafana-deployment.yaml @@ -0,0 +1,59 @@ +{{- if .Values.grafana.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "open-meteo-service.grafanaFullname" . }} + labels: + {{- include "open-meteo-service.labels" . | nindent 4 }} + app.kubernetes.io/component: grafana +spec: + replicas: {{ .Values.grafana.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "open-meteo-service.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: grafana + template: + metadata: + labels: + {{- include "open-meteo-service.labels" . | nindent 8 }} + app.kubernetes.io/component: grafana + spec: + containers: + - name: grafana + image: {{ .Values.grafana.image | quote }} + ports: + - name: http + containerPort: {{ .Values.grafana.service.port }} + protocol: TCP + env: + - name: GF_SECURITY_ADMIN_USER + value: {{ .Values.grafana.adminUser | quote }} + - name: GF_SECURITY_ADMIN_PASSWORD + value: {{ .Values.grafana.adminPassword | quote }} + volumeMounts: + - name: grafana-config + mountPath: /etc/grafana/provisioning/datasources/datasource.yml + subPath: datasource.yml + - name: grafana-config + mountPath: /etc/grafana/provisioning/dashboards/dashboard.yml + subPath: dashboard.yml + - name: grafana-config + mountPath: /var/lib/grafana/dashboards/open-meteo-service.json + subPath: open-meteo-service.json + - name: grafana-data + mountPath: /var/lib/grafana + resources: + {{- toYaml .Values.grafana.resources | nindent 12 }} + volumes: + - name: grafana-config + configMap: + name: {{ include "open-meteo-service.grafanaFullname" . }}-config + - name: grafana-data + {{- if .Values.grafana.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ include "open-meteo-service.grafanaFullname" . }} + {{- else }} + emptyDir: {} + {{- end }} +{{- end }} diff --git a/open-meteo-service/templates/grafana-ingress.yaml b/open-meteo-service/templates/grafana-ingress.yaml new file mode 100644 index 0000000..236f530 --- /dev/null +++ b/open-meteo-service/templates/grafana-ingress.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.grafana.enabled .Values.grafana.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "open-meteo-service.grafanaFullname" . }} + {{- if .Values.grafana.ingress.className }} + annotations: + kubernetes.io/ingress.class: {{ .Values.grafana.ingress.className }} + {{- end }} +spec: + {{- if .Values.grafana.ingress.className }} + ingressClassName: {{ .Values.grafana.ingress.className }} + {{- end }} + rules: + {{- range .Values.grafana.ingress.hosts }} + - host: {{ .host }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ include "open-meteo-service.grafanaFullname" $ }} + port: + number: {{ $.Values.grafana.service.port }} + {{- end }} + {{- end }} + {{- if .Values.grafana.ingress.tls }} + tls: + {{- toYaml .Values.grafana.ingress.tls | nindent 4 }} + {{- end }} +{{- end }} diff --git a/open-meteo-service/templates/grafana-service.yaml b/open-meteo-service/templates/grafana-service.yaml new file mode 100644 index 0000000..e1d9043 --- /dev/null +++ b/open-meteo-service/templates/grafana-service.yaml @@ -0,0 +1,20 @@ +{{- if .Values.grafana.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "open-meteo-service.grafanaFullname" . }} + labels: + {{- include "open-meteo-service.labels" . | nindent 4 }} + app.kubernetes.io/component: grafana +spec: + type: {{ .Values.grafana.service.type }} + ports: + - port: {{ .Values.grafana.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + app.kubernetes.io/name: {{ include "open-meteo-service.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: grafana +{{- end }} diff --git a/open-meteo-service/templates/ingress.yaml b/open-meteo-service/templates/ingress.yaml new file mode 100644 index 0000000..a5777ec --- /dev/null +++ b/open-meteo-service/templates/ingress.yaml @@ -0,0 +1,33 @@ +{{- if .Values.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "open-meteo-service.fullname" . }} + {{- if .Values.ingress.className }} + annotations: + kubernetes.io/ingress.class: {{ .Values.ingress.className }} + {{- end }} +spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ include "open-meteo-service.fullname" $ }} + port: + number: {{ $.Values.service.port }} + {{- end }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- toYaml .Values.ingress.tls | nindent 4 }} + {{- end }} +{{- end }} diff --git a/open-meteo-service/templates/prometheus-configmap.yaml b/open-meteo-service/templates/prometheus-configmap.yaml new file mode 100644 index 0000000..35b7b7b --- /dev/null +++ b/open-meteo-service/templates/prometheus-configmap.yaml @@ -0,0 +1,23 @@ +{{- if .Values.prometheus.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "open-meteo-service.prometheusFullname" . }} + labels: + {{- include "open-meteo-service.labels" . | nindent 4 }} + app.kubernetes.io/component: prometheus +data: + prometheus.yml: |- + global: + scrape_interval: 15s + + scrape_configs: + - job_name: "prometheus" + static_configs: + - targets: ["{{ include "open-meteo-service.prometheusFullname" . }}:{{ .Values.prometheus.service.port }}"] + + - job_name: "open-meteo-service" + metrics_path: "/metrics" + static_configs: + - targets: ["{{ include "open-meteo-service.fullname" . }}:{{ .Values.service.port }}"] +{{- end }} diff --git a/open-meteo-service/templates/prometheus-deployment.yaml b/open-meteo-service/templates/prometheus-deployment.yaml new file mode 100644 index 0000000..d471a0f --- /dev/null +++ b/open-meteo-service/templates/prometheus-deployment.yaml @@ -0,0 +1,54 @@ +{{- if .Values.prometheus.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "open-meteo-service.prometheusFullname" . }} + labels: + {{- include "open-meteo-service.labels" . | nindent 4 }} + app.kubernetes.io/component: prometheus +spec: + replicas: {{ .Values.prometheus.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "open-meteo-service.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: prometheus + template: + metadata: + labels: + {{- include "open-meteo-service.labels" . | nindent 8 }} + app.kubernetes.io/component: prometheus + spec: + containers: + - name: prometheus + image: {{ .Values.prometheus.image | quote }} + ports: + - name: http + containerPort: {{ .Values.prometheus.service.port }} + protocol: TCP + args: + - "--config.file=/etc/prometheus/prometheus.yml" + - "--storage.tsdb.path=/prometheus" + {{- range .Values.prometheus.extraArgs }} + - {{ . | quote }} + {{- end }} + volumeMounts: + - name: prometheus-config + mountPath: /etc/prometheus/prometheus.yml + subPath: prometheus.yml + - name: prometheus-data + mountPath: /prometheus + resources: + {{- toYaml .Values.prometheus.resources | nindent 12 }} + volumes: + - name: prometheus-config + configMap: + name: {{ include "open-meteo-service.prometheusFullname" . }} + - name: prometheus-data + {{- if .Values.prometheus.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ include "open-meteo-service.prometheusFullname" . }} + {{- else }} + emptyDir: {} + {{- end }} +{{- end }} diff --git a/open-meteo-service/templates/prometheus-ingress.yaml b/open-meteo-service/templates/prometheus-ingress.yaml new file mode 100644 index 0000000..21e9c79 --- /dev/null +++ b/open-meteo-service/templates/prometheus-ingress.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.prometheus.enabled .Values.prometheus.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "open-meteo-service.prometheusFullname" . }} + {{- if .Values.prometheus.ingress.className }} + annotations: + kubernetes.io/ingress.class: {{ .Values.prometheus.ingress.className }} + {{- end }} +spec: + {{- if .Values.prometheus.ingress.className }} + ingressClassName: {{ .Values.prometheus.ingress.className }} + {{- end }} + rules: + {{- range .Values.prometheus.ingress.hosts }} + - host: {{ .host }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ include "open-meteo-service.prometheusFullname" $ }} + port: + number: {{ $.Values.prometheus.service.port }} + {{- end }} + {{- end }} + {{- if .Values.prometheus.ingress.tls }} + tls: + {{- toYaml .Values.prometheus.ingress.tls | nindent 4 }} + {{- end }} +{{- end }} diff --git a/open-meteo-service/templates/prometheus-service.yaml b/open-meteo-service/templates/prometheus-service.yaml new file mode 100644 index 0000000..be87462 --- /dev/null +++ b/open-meteo-service/templates/prometheus-service.yaml @@ -0,0 +1,20 @@ +{{- if .Values.prometheus.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "open-meteo-service.prometheusFullname" . }} + labels: + {{- include "open-meteo-service.labels" . | nindent 4 }} + app.kubernetes.io/component: prometheus +spec: + type: {{ .Values.prometheus.service.type }} + ports: + - port: {{ .Values.prometheus.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + app.kubernetes.io/name: {{ include "open-meteo-service.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: prometheus +{{- end }} diff --git a/open-meteo-service/templates/pvc.yaml b/open-meteo-service/templates/pvc.yaml new file mode 100644 index 0000000..b02c70d --- /dev/null +++ b/open-meteo-service/templates/pvc.yaml @@ -0,0 +1,57 @@ +{{- if .Values.persistence.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "open-meteo-service.fullname" . }} + labels: + {{- include "open-meteo-service.labels" . | nindent 4 }} +spec: + accessModes: + {{- toYaml .Values.persistence.accessModes | nindent 4 }} + resources: + requests: + storage: {{ .Values.persistence.size }} + {{- if .Values.persistence.storageClassName }} + storageClassName: {{ .Values.persistence.storageClassName | quote }} + {{- end }} +{{- end }} + +{{- if .Values.prometheus.persistence.enabled }} +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "open-meteo-service.prometheusFullname" . }} + labels: + {{- include "open-meteo-service.labels" . | nindent 4 }} + app.kubernetes.io/component: prometheus +spec: + accessModes: + {{- toYaml .Values.prometheus.persistence.accessModes | nindent 4 }} + resources: + requests: + storage: {{ .Values.prometheus.persistence.size }} + {{- if .Values.prometheus.persistence.storageClassName }} + storageClassName: {{ .Values.prometheus.persistence.storageClassName | quote }} + {{- end }} +{{- end }} + +{{- if .Values.grafana.persistence.enabled }} +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "open-meteo-service.grafanaFullname" . }} + labels: + {{- include "open-meteo-service.labels" . | nindent 4 }} + app.kubernetes.io/component: grafana +spec: + accessModes: + {{- toYaml .Values.grafana.persistence.accessModes | nindent 4 }} + resources: + requests: + storage: {{ .Values.grafana.persistence.size }} + {{- if .Values.grafana.persistence.storageClassName }} + storageClassName: {{ .Values.grafana.persistence.storageClassName | quote }} + {{- end }} +{{- end }} diff --git a/open-meteo-service/templates/service.yaml b/open-meteo-service/templates/service.yaml new file mode 100644 index 0000000..3c91b8d --- /dev/null +++ b/open-meteo-service/templates/service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "open-meteo-service.fullname" . }} + labels: + {{- include "open-meteo-service.labels" . | nindent 4 }} + app.kubernetes.io/component: api +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "open-meteo-service.selectorLabels" . | nindent 4 }} diff --git a/open-meteo-service/values.yaml b/open-meteo-service/values.yaml new file mode 100644 index 0000000..27de93a --- /dev/null +++ b/open-meteo-service/values.yaml @@ -0,0 +1,97 @@ +replicaCount: 1 + +image: + repository: harbor.dvirlabs.com/my-apps/open-meteo-service + tag: "1.0.2" + pullPolicy: IfNotPresent + +imagePullSecrets: + - name: harbor-regcred + +service: + type: ClusterIP + port: 8000 + +ingress: + enabled: true + className: "traefik" + hosts: + - host: open-meteo.dvirlabs.com + paths: + - path: / + pathType: Prefix + tls: [] + +podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/path: /metrics + prometheus.io/port: "8000" + +env: + cacheFile: /data/coordinates_cache.json + +persistence: + enabled: false + accessModes: + - ReadWriteOnce + size: 1Gi + storageClassName: "" + +resources: {} + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +prometheus: + enabled: true + replicaCount: 1 + image: prom/prometheus:latest + service: + type: ClusterIP + port: 9090 + ingress: + enabled: true + className: "traefik" + hosts: + - host: open-meteo-prometheus.dvirlabs.com + paths: + - path: / + pathType: Prefix + tls: [] + persistence: + enabled: false + accessModes: + - ReadWriteOnce + size: 5Gi + storageClassName: "" + resources: {} + extraArgs: [] + +grafana: + enabled: true + replicaCount: 1 + image: grafana/grafana:latest + service: + type: ClusterIP + port: 3000 + adminUser: admin + adminPassword: admin + ingress: + enabled: true + className: "traefik" + hosts: + - host: open-meteo-grafana.dvirlabs.com + paths: + - path: / + pathType: Prefix + tls: [] + persistence: + enabled: false + accessModes: + - ReadWriteOnce + size: 5Gi + storageClassName: "" + resources: {} \ No newline at end of file