diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ba14cee17957..156aee91395d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -24,6 +24,7 @@ /charts/prometheus-fastly-exporter/ @arslanbekov /charts/prometheus-json-exporter/ @schmiddim @xiu @zanhsieh /charts/prometheus-kafka-exporter/ @gkarthiks @golgoth31 @zeritti +/charts/prometheus-modbus-exporter/ @openenergyprojects /charts/prometheus-mongodb-exporter/ @steven-sheehy @zeritti /charts/prometheus-mysql-exporter/ @juanchimienti @monotek /charts/prometheus-nats-exporter/ @caarlos0 @okgolove diff --git a/charts/prometheus-modbus-exporter/Chart.yaml b/charts/prometheus-modbus-exporter/Chart.yaml new file mode 100644 index 000000000000..b715fa4ec403 --- /dev/null +++ b/charts/prometheus-modbus-exporter/Chart.yaml @@ -0,0 +1,19 @@ +apiVersion: v2 +name: prometheus-modbus-exporter +description: A Helm chart for prometheus-modbus-exporter + +keywords: + - modbus + - modbus_exporter + - metric + - monitoring + - prometheus + +type: application + +version: 0.1.0 +appVersion: "0.4.0" + +maintainers: + - name: openenergyprojects + email: openenergyprojects@gmail.com diff --git a/charts/prometheus-modbus-exporter/README.md b/charts/prometheus-modbus-exporter/README.md new file mode 100644 index 000000000000..02ab7771b128 --- /dev/null +++ b/charts/prometheus-modbus-exporter/README.md @@ -0,0 +1,80 @@ +# prometheus-modbus-exporter + +Prometheus exporter for scraping metrics via modbus based protocol. + +## Intro + +This chart bootstraps a [modbus_exporter](https://github.com/RichiH/modbus_exporter) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +The serviceMonitor objects are created for Prometheus Operator. + +## Configuration + +The configuration of the modbus_exporter can be provided either via helm's custom values, or via an already existing (independently managed) configMap. +Either way, every time the configuration is getting updated, the modbus_exporter is getting restarted in order to fetch it. This is done using sidecar reloader: . + +## Tests + +This setup has been tested with both real unit (Janitza Power Analizer UMG series) as well as using an simulator . +Other simulators (fully free) exist as well: + +1. the one included as part of the test (fake server) in the , which uses (golang). +2. Many others, like pymodslave, based on py module: , which has its own demo simulator as well. + +## Notes + +There are 4 types of read registries, hence 4 read function codes (1,2,3,4). +Don't forget to prefix (first digit) your registry with the required function. +Your address should be always 6 digits. +E.g. for holding registry 22, the address is: 300022 (where the 3 denotes the holding registry function). +More on Modbus function codes: + +## Prerequisites + +- Kubernetes 1.10+ with Beta APIs enabled +- Helm 3+ + +## Get Repository Info + +```console +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm repo update +``` + +_See [helm repository](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +```console +helm install [RELEASE_NAME] prometheus-community/prometheus-modbus-exporter +``` + +_See [configuration](## Configuring) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +```console +helm uninstall [RELEASE_NAME] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrading Chart + +```console +helm upgrade [RELEASE_NAME] [CHART] --install +``` + +## Configuring + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments, visit the chart's [values.yaml](./values.yaml), or run these configuration commands: + +```console +helm show values prometheus-community/prometheus-modbus-exporter +``` + +For more information please refer to the [modbus_exporter](https://github.com/RichiH/modbus_exporter) documentation. diff --git a/charts/prometheus-modbus-exporter/templates/NOTES.txt b/charts/prometheus-modbus-exporter/templates/NOTES.txt new file mode 100644 index 000000000000..09e605d6f843 --- /dev/null +++ b/charts/prometheus-modbus-exporter/templates/NOTES.txt @@ -0,0 +1,3 @@ +For any help, see: +- https://github.com/RichiH/modbus_exporter +- https://github.com/prometheus-community/helm-charts/issues diff --git a/charts/prometheus-modbus-exporter/templates/_helpers.tpl b/charts/prometheus-modbus-exporter/templates/_helpers.tpl new file mode 100644 index 000000000000..a1f860fa7dcf --- /dev/null +++ b/charts/prometheus-modbus-exporter/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "prometheus-modbus-exporter.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 "prometheus-modbus-exporter.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 "prometheus-modbus-exporter.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "prometheus-modbus-exporter.labels" -}} +helm.sh/chart: {{ include "prometheus-modbus-exporter.chart" . }} +{{ include "prometheus-modbus-exporter.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "prometheus-modbus-exporter.selectorLabels" -}} +app.kubernetes.io/name: {{ include "prometheus-modbus-exporter.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "prometheus-modbus-exporter.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "prometheus-modbus-exporter.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/prometheus-modbus-exporter/templates/configmap.yaml b/charts/prometheus-modbus-exporter/templates/configmap.yaml new file mode 100644 index 000000000000..3885f086ef28 --- /dev/null +++ b/charts/prometheus-modbus-exporter/templates/configmap.yaml @@ -0,0 +1,13 @@ +{{- if not .Values.configMapFile -}} +{{- $fullName := include "prometheus-modbus-exporter.fullname" . -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ $fullName }} + labels: + {{- include "prometheus-modbus-exporter.labels" . | nindent 4 }} +data: + modbus.yml: | + modules: +{{- toYaml .Values.modules | nindent 4 }} +{{- end }} diff --git a/charts/prometheus-modbus-exporter/templates/deployment.yaml b/charts/prometheus-modbus-exporter/templates/deployment.yaml new file mode 100644 index 000000000000..48a3c09f9789 --- /dev/null +++ b/charts/prometheus-modbus-exporter/templates/deployment.yaml @@ -0,0 +1,88 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "prometheus-modbus-exporter.fullname" . }} + labels: + {{- include "prometheus-modbus-exporter.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "prometheus-modbus-exporter.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "prometheus-modbus-exporter.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "prometheus-modbus-exporter.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + shareProcessNamespace: true # required for config-reloader-sidecar + containers: + - name: {{ include "prometheus-modbus-exporter.fullname" . }} + command: ["/bin/modbus_exporter"] + args: + - "--config.file=/etc/modbus_exporter/modbus.yml" + - "--log.level={{ .Values.log.level }}" + - "--log.format={{ .Values.log.format }}" + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: metrics + containerPort: {{ .Values.service.port }} + protocol: TCP + livenessProbe: + httpGet: + path: /metrics + port: 9602 + readinessProbe: + httpGet: + path: /metrics + port: 9602 + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: configfile + mountPath: /etc/modbus_exporter/ + {{ if .Values.configReloaderSidecar.enable }} + - name: {{ include "prometheus-modbus-exporter.fullname" . }}-config-reloader-sidecar + image: "{{ .Values.configReloaderSidecar.image.repository }}:{{ .Values.configReloaderSidecar.image.tag }}" + env: + - name: CONFIG_DIR + value: /etc/modbus_exporter/ + - name: PROCESS_NAME + value: modbus_exporter + volumeMounts: + - name: configfile + mountPath: /etc/modbus_exporter/ + {{- end -}} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: configfile + configMap: + {{- if not .Values.configMapFile }} + name: {{ include "prometheus-modbus-exporter.fullname" . }} + {{- else }} + name: {{ .Values.configMapFile }} + {{- end }} diff --git a/charts/prometheus-modbus-exporter/templates/service.yaml b/charts/prometheus-modbus-exporter/templates/service.yaml new file mode 100644 index 000000000000..6b3ccf9771b2 --- /dev/null +++ b/charts/prometheus-modbus-exporter/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "prometheus-modbus-exporter.fullname" . }} + labels: + {{- include "prometheus-modbus-exporter.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: 9602 + protocol: TCP + name: metrics + selector: + {{- include "prometheus-modbus-exporter.selectorLabels" . | nindent 4 }} diff --git a/charts/prometheus-modbus-exporter/templates/serviceaccount.yaml b/charts/prometheus-modbus-exporter/templates/serviceaccount.yaml new file mode 100644 index 000000000000..b78de606191c --- /dev/null +++ b/charts/prometheus-modbus-exporter/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "prometheus-modbus-exporter.serviceAccountName" . }} + labels: + {{- include "prometheus-modbus-exporter.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/prometheus-modbus-exporter/templates/servicemonitor.yaml b/charts/prometheus-modbus-exporter/templates/servicemonitor.yaml new file mode 100644 index 000000000000..58223cccec47 --- /dev/null +++ b/charts/prometheus-modbus-exporter/templates/servicemonitor.yaml @@ -0,0 +1,52 @@ +{{- $fullName := include "prometheus-modbus-exporter.fullname" . -}} +{{- $endpointsCommonConfig := .Values.serviceMonitor.endpointsCommonConfig -}} +{{- if and .Values.serviceMonitor.enabled ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1/ServiceMonitor" ) }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ $fullName }} + labels: + {{- include "prometheus-modbus-exporter.labels" . | nindent 4 }} + {{- with .Values.serviceMonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.serviceMonitor.annotations }} + annotations: + {{ toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "prometheus-modbus-exporter.labels" . | nindent 6 }} + endpoints: + {{- range .Values.serviceMonitor.endpointsConfig }} + - port: metrics + path: "/modbus" +{{ toYaml . | indent 4 }} + {{/*path: "/modbus&target=1.2.3.4:502" */}} + {{ toYaml $endpointsCommonConfig | nindent 4 }} + {{- end }} +{{- end }} +--- +{{- if and .Values.serviceMonitorExporterItself.enabled ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1/ServiceMonitor" ) }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ $fullName }}-self-monitor + labels: + {{- include "prometheus-modbus-exporter.labels" . | nindent 4 }} + {{- with .Values.serviceMonitorExporterItself.labels }} + {{ toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.serviceMonitorExporterItself.annotations }} + annotations: + {{ toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "prometheus-modbus-exporter.labels" . | nindent 6 }} + endpoints: + - port: metrics + path: "/metrics" +{{- end }} diff --git a/charts/prometheus-modbus-exporter/templates/tests/test-connection.yaml b/charts/prometheus-modbus-exporter/templates/tests/test-connection.yaml new file mode 100644 index 000000000000..d6ddf6bdbd26 --- /dev/null +++ b/charts/prometheus-modbus-exporter/templates/tests/test-connection.yaml @@ -0,0 +1,17 @@ +{{/* +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "prometheus-modbus-exporter.fullname" . }}-test-connection" + labels: + {{- include "prometheus-modbus-exporter.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "prometheus-modbus-exporter.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never +*/}} diff --git a/charts/prometheus-modbus-exporter/values.yaml b/charts/prometheus-modbus-exporter/values.yaml new file mode 100644 index 000000000000..3f0883ab0cf5 --- /dev/null +++ b/charts/prometheus-modbus-exporter/values.yaml @@ -0,0 +1,165 @@ +# Default values for prometheus-modbus-exporter. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +## if one needs to define the below modbus.yml in a separate configMap +## that configMap name can be mentioned here: +# configMapFile: "my-existing-modbus-config" + +## when the above configMapFile parameter is not defined, it will be created +## using below parameters (usually send to the chart as custom values) +modules: +# Module name, needs to be passed as parameter by Prometheus. +# the name must be matched with the name of serviceMonitor.endpointsConfig[x].params.module +- name: "fake" + protocol: 'tcp/ip' + metrics: + # Name of the metric. + - name: "power_consumption_total" + # Help text of the metric. + help: "represents the overall power consumption by phase" + # Labels to be added to the time series. + labels: + phase: "1" + # Register address. + # The first digit of the address is the function code + # Supported codes are: 1, 2, 3, 4 + address: 300022 + # Datatypes allowed: bool, int16, int32, int64, uint16, uint32, uint64, + # float16, float32, float64 + # One register holds 16 bits. + dataType: int16 + # Endianness allowed: big, little, mixed, yolo + # Optional. If not defined: big. + endianness: big + # Prometheus metric type: https://prometheus.io/docs/concepts/metric_types/. + metricType: counter + # Factor can be specified to represent metric value. + # Examples: 1, 2, 1.543, 0.01 etc + # Factor is multiplied with the scraped value to produce the metric value + # Optional. + factor: 3.1415926535 + + - name: "some_gauge" + help: "some help for some gauge" + address: 30023 + dataType: int16 + metricType: gauge + factor: 2 + + - name: "coil" + help: "some help for some coil" + address: 124 + dataType: bool + bitOffset: 0 + metricType: gauge + +## The prometheus operator serviceMonitor for modbus +serviceMonitor: + ## even if enabled is true, if serviceMonitor crd is not installed, this will be skipped. + enabled: true + endpointsConfig: + - params: + target: + - "10.1.2.3:502" + module: + ## module listed must be matched with the module[x].name specified in section above + - "fake" + sub_target: + - "1" + ## configurations common for all above endpoints: + endpointsCommonConfig: + ## https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#monitoring.coreos.com/v1.Endpoint + scheme: http + interval: 10s + scrapeTimeout: 1s + metricRelabelings: [] + relabelings: [] + followRedirects: true + # enableHttp2: false + annotations: {} + labels: + release: prometheus + +log: + ## choose one: debug,info,warn,error + level: "info" + ## logfmt,json + format: "logfmt" + +## The prometheus operator serviceMonitor for exporter itself +serviceMonitorExporterItself: + enabled: true + annotations: {} + labels: + release: prometheus + +image: + registry: docker.io + # repository: richih/modbus_exporter + repository: openenergyprojects/modbus_exporter + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "20230617_a144551" + +configReloaderSidecar: + enabled: true + image: + registry: docker.io + repository: openenergyprojects/config-reloader-sidecar + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "20230519_90573b0" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +podSecurityContext: +# runAsGroup: 65534 +# runAsUser: 65534 +# fsGroup: 65534 + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + +securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true +# runAsUser: 1000 + +service: + type: ClusterIP + port: 9602 + +resources: {} +# We usually recommend not to specify default resources and to leave this as a conscious +# choice for the user. This also increases chances charts run on environments with little +# resources, such as Minikube. If you do want to specify resources, uncomment the following +# lines, adjust them as necessary, and remove the curly braces after 'resources:'. +# limits: +# cpu: 100m +# memory: 128Mi +# requests: +# cpu: 100m +# memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {}