From 4e1830f3c74a53713336cc6c6cee2c782689312d Mon Sep 17 00:00:00 2001
From: Pete Wall <pete.wall@grafana.com>
Date: Fri, 7 Feb 2025 11:37:20 -0600
Subject: [PATCH] Add the ability to set an additional service for the recevier

Signed-off-by: Pete Wall <pete.wall@grafana.com>
---
 charts/k8s-monitoring/README.md               |   3 +
 .../templates/receiver-service.yaml           |  42 +++++++
 .../tests/receiver-service_test.yaml          | 109 ++++++++++++++++++
 charts/k8s-monitoring/values.schema.json      |  14 +++
 charts/k8s-monitoring/values.yaml             |  12 ++
 5 files changed, 180 insertions(+)
 create mode 100644 charts/k8s-monitoring/templates/receiver-service.yaml
 create mode 100644 charts/k8s-monitoring/tests/receiver-service_test.yaml

diff --git a/charts/k8s-monitoring/README.md b/charts/k8s-monitoring/README.md
index 99ce941eb1..0ed24e71ae 100644
--- a/charts/k8s-monitoring/README.md
+++ b/charts/k8s-monitoring/README.md
@@ -230,6 +230,9 @@ podLogs:
 | alloy-receiver.controller.type | string | `"daemonset"` | The type of controller to use for the Alloy Receiver instance. |
 | alloy-receiver.enabled | bool | `false` | Deploy the Alloy instance for opening receivers to collect application data. |
 | alloy-receiver.extraConfig | string | `""` | Extra Alloy configuration to be added to the configuration file. |
+| alloy-receiver.extraService.enabled | bool | `false` | Create an extra service for the Alloy receiver. This service will mirror the alloy-receiver service, but its name can be customized to match existing application settings. |
+| alloy-receiver.extraService.fullname | string | `""` | If set, the full name of the extra service to create. This will result in the format `<fullname>`. |
+| alloy-receiver.extraService.name | string | `"alloy"` | The name of the extra service to create. This will result in the format `<release-name>-<name>`. |
 | alloy-receiver.liveDebugging.enabled | bool | `false` | Enable live debugging for the Alloy instance. Requires stability level to be set to "experimental". |
 | alloy-receiver.logging.format | string | `"logfmt"` | Format to use for writing Alloy log lines. |
 | alloy-receiver.logging.level | string | `"info"` | Level at which Alloy log lines should be written. |
diff --git a/charts/k8s-monitoring/templates/receiver-service.yaml b/charts/k8s-monitoring/templates/receiver-service.yaml
new file mode 100644
index 0000000000..29d83c2a23
--- /dev/null
+++ b/charts/k8s-monitoring/templates/receiver-service.yaml
@@ -0,0 +1,42 @@
+{{- if and (index .Values "alloy-receiver").enabled (index .Values "alloy-receiver").extraService.enabled -}}
+{{- $name := printf "%s-%s" .Release.Name (index .Values "alloy-receiver").extraService.name | trunc 63 | trimSuffix "-" }}
+{{- if (index .Values "alloy-receiver").extraService.fullname }}
+  {{- $name = (index .Values "alloy-receiver").extraService.fullname }}
+{{- end }}
+
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ $name }}
+  labels:
+    {{- include "alloy.labels" (index .Subcharts "alloy-receiver") | nindent 4 }}
+    app.kubernetes.io/component: networking
+  {{- with (index .Values "alloy-receiver").service.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+  type: {{ (index .Values "alloy-receiver").service.type }}
+  {{- if (index .Values "alloy-receiver").service.clusterIP }}
+  clusterIP: {{ (index .Values "alloy-receiver").service.clusterIP }}
+  {{- end }}
+  selector:
+    {{- include "alloy.selectorLabels" . | nindent 4 }}
+  {{- if semverCompare ">=1.26-0" .Capabilities.KubeVersion.Version }}
+  internalTrafficPolicy: {{ (index .Values "alloy-receiver").service.internalTrafficPolicy}}
+  {{- end }}
+  ports:
+    - name: http-metrics
+      {{- if eq (index .Values "alloy-receiver").service.type "NodePort" }}
+      nodePort: {{ (index .Values "alloy-receiver").service.nodePort }}
+      {{- end }}
+      port: {{ (index .Values "alloy-receiver").alloy.listenPort }}
+      targetPort: {{ (index .Values "alloy-receiver").alloy.listenPort }}
+      protocol: "TCP"
+{{- range $portMap := (index .Values "alloy-receiver").alloy.extraPorts }}
+    - name: {{ $portMap.name }}
+      port: {{ $portMap.port }}
+      targetPort: {{ $portMap.targetPort }}
+      protocol: {{ coalesce $portMap.protocol "TCP" }}
+{{- end }}
+{{- end }}
diff --git a/charts/k8s-monitoring/tests/receiver-service_test.yaml b/charts/k8s-monitoring/tests/receiver-service_test.yaml
new file mode 100644
index 0000000000..5b448fdaa2
--- /dev/null
+++ b/charts/k8s-monitoring/tests/receiver-service_test.yaml
@@ -0,0 +1,109 @@
+# yamllint disable rule:document-start rule:line-length rule:trailing-spaces
+suite: Test Extra Receiver Service
+templates:
+  - receiver-service.yaml
+tests:
+  - it: does not create a Service by default
+    set:
+      cluster: {name: test-cluster}
+      alloy-receiver:
+        enabled: true
+        extraConfig: " "
+    asserts:
+      - hasDocuments:
+          count: 0
+
+  - it: creates a Service when enabled
+    set:
+      cluster: {name: test-cluster}
+      alloy-receiver:
+        enabled: true
+        extraConfig: " "
+        extraService:
+          enabled: true
+    asserts:
+      - hasDocuments:
+          count: 1
+      - isKind:
+          of: Service
+      - equal:
+          path: metadata.name
+          value: RELEASE-NAME-alloy
+
+  - it: creates a Service with a specified name
+    set:
+      cluster: {name: test-cluster}
+      alloy-receiver:
+        enabled: true
+        extraConfig: " "
+        extraService:
+          enabled: true
+          name: alloy-ingester
+    asserts:
+      - hasDocuments:
+          count: 1
+      - isKind:
+          of: Service
+      - equal:
+          path: metadata.name
+          value: RELEASE-NAME-alloy-ingester
+
+  - it: creates a Service with a specified full name
+    set:
+      cluster: {name: test-cluster}
+      alloy-receiver:
+        enabled: true
+        extraConfig: " "
+        extraService:
+          enabled: true
+          fullname: alloy-ingester
+    asserts:
+      - hasDocuments:
+          count: 1
+      - isKind:
+          of: Service
+      - equal:
+          path: metadata.name
+          value: alloy-ingester
+
+  - it: has the same extraPorts as the main receiver
+    set:
+      cluster: {name: test-cluster}
+      alloy-receiver:
+        enabled: true
+        extraConfig: " "
+        alloy:
+          extraPorts:
+          - name: otlp-http
+            port: 4318
+            targetPort: 4318
+            protocol: TCP
+          - name: otlp-grpc
+            port: 4317
+            targetPort: 4317
+            protocol: TCP
+        extraService:
+          enabled: true
+    asserts:
+      - hasDocuments:
+          count: 1
+      - isKind:
+          of: Service
+      - equal:
+          path: spec.ports
+          value:
+            - name: http-metrics
+              port: 12345
+              targetPort: 12345
+              protocol: TCP
+            - name: otlp-http
+              port: 4318
+              targetPort: 4318
+              protocol: TCP
+            - name: otlp-grpc
+              port: 4317
+              targetPort: 4317
+              protocol: TCP
+
+
+
diff --git a/charts/k8s-monitoring/values.schema.json b/charts/k8s-monitoring/values.schema.json
index ff02bd07c4..6c72b275cd 100644
--- a/charts/k8s-monitoring/values.schema.json
+++ b/charts/k8s-monitoring/values.schema.json
@@ -646,6 +646,20 @@
                 "extraConfig": {
                     "type": "string"
                 },
+                "extraService": {
+                    "type": "object",
+                    "properties": {
+                        "enabled": {
+                            "type": "boolean"
+                        },
+                        "fullname": {
+                            "type": "string"
+                        },
+                        "name": {
+                            "type": "string"
+                        }
+                    }
+                },
                 "liveDebugging": {
                     "type": "object",
                     "properties": {
diff --git a/charts/k8s-monitoring/values.yaml b/charts/k8s-monitoring/values.yaml
index 59c3b47a1f..cd6fa17c03 100644
--- a/charts/k8s-monitoring/values.yaml
+++ b/charts/k8s-monitoring/values.yaml
@@ -770,6 +770,18 @@ alloy-receiver:
   # @ignored
   crds: {create: false}
 
+  extraService:
+    # -- Create an extra service for the Alloy receiver. This service will mirror the alloy-receiver service, but its
+    # name can be customized to match existing application settings.
+    # @section -- Collectors - Alloy Receiver
+    enabled: false
+    # -- The name of the extra service to create. This will result in the format `<release-name>-<name>`.
+    # @section -- Collectors - Alloy Receiver
+    name: alloy
+    # -- If set, the full name of the extra service to create. This will result in the format `<fullname>`.
+    # @section -- Collectors - Alloy Receiver
+    fullname: ""
+
 # An Alloy instance for gathering profiles.
 # To see additional valid options, please see the [Alloy Helm chart documentation](https://github.com/grafana/alloy/tree/main/operations/helm/charts/alloy).
 alloy-profiles: