Repository: mariadb-operator/mariadb-operator

Issue:
[Feature] Add command Parameter to Exporter Object
It would be helpful to allow the configuration of a custom command for the Exporter container in the MariaDB Operator. This would enable users to override default parameters for the mysqld-exporter, providing greater flexibility in customizing its behavior.


**Describe the solution you'd like**
The current implementation of the Exporter object does not provide a way to override the command of the mysqld-exporter container. This feature would be beneficial in scenarios where users need to:

- Adjust the metrics collection parameters for the exporter.
- Specify custom flags for the mysqld-exporter.
- Fine-tune the behavior of the exporter container for specific monitoring needs.

**Example command:**

```
 - /bin/mysqld_exporter
        - --collect.binlog_size
        - --collect.engine_innodb_status
        - --collect.global_status
        - --collect.global_variables
        - --collect.info_schema.clientstats
        - --collect.info_schema.innodb_metrics
        - --collect.info_schema.innodb_tablespaces
        - --collect.info_schema.processlist
        - --collect.info_schema.tables
        - --collect.info_schema.tablestats
        - --collect.info_schema.schemastats
        - --collect.info_schema.userstats
        - --collect.perf_schema.eventsstatementssum
        - --collect.perf_schema.file_events
        - --collect.perf_schema.file_instances
        - --collect.perf_schema.indexiowaits
        - --collect.perf_schema.memory_events
        - --collect.perf_schema.tableiowaits
        - --collect.perf_schema.tablelocks
        - --collect.slave_status
   ```


Discussion:
@pschiffe: I was just looking for this option.@pschiffe: Related feature to this would be option to modify `relabelings` of `serviceMonitor`s, for example, I would like to add `node_name` label to mysql metrics.

Solution patch:
diff --git a/api/v1alpha1/base_types.go b/api/v1alpha1/base_types.go
index aa19a461..c8b47877 100644
--- a/api/v1alpha1/base_types.go
+++ b/api/v1alpha1/base_types.go
@@ -795,6 +795,10 @@ type Exporter struct {
 	// +optional
 	// +operator-sdk:csv:customresourcedefinitions:type=spec
 	ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" webhook:"inmutable"`
+	// Args to be used in the Container.
+	// +optional
+	// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"}
+	Args []string `json:"args,omitempty"`
 	// Port where the exporter will be listening for connections.
 	// +optional
 	// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:number"}
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index c84b9818..cbf2585d 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -945,6 +945,11 @@ func (in *Exporter) DeepCopyInto(out *Exporter) {
 		*out = make([]LocalObjectReference, len(*in))
 		copy(*out, *in)
 	}
+	if in.Args != nil {
+		in, out := &in.Args, &out.Args
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
 	if in.Resources != nil {
 		in, out := &in.Resources, &out.Resources
 		*out = new(ResourceRequirements)
diff --git a/config/crd/bases/k8s.mariadb.com_mariadbs.yaml b/config/crd/bases/k8s.mariadb.com_mariadbs.yaml
index 08c05cec..7360ebc9 100644
--- a/config/crd/bases/k8s.mariadb.com_mariadbs.yaml
+++ b/config/crd/bases/k8s.mariadb.com_mariadbs.yaml
@@ -3204,6 +3204,11 @@ spec:
                                     x-kubernetes-list-type: atomic
                                 type: object
                             type: object
+                          args:
+                            description: Args to be used in the Container.
+                            items:
+                              type: string
+                            type: array
                           image:
                             description: |-
                               Image name to be used as metrics exporter. The supported format is `<image>:<tag>`.
@@ -4030,6 +4035,11 @@ spec:
                                 x-kubernetes-list-type: atomic
                             type: object
                         type: object
+                      args:
+                        description: Args to be used in the Container.
+                        items:
+                          type: string
+                        type: array
                       image:
                         description: |-
                           Image name to be used as metrics exporter. The supported format is `<image>:<tag>`.
diff --git a/config/crd/bases/k8s.mariadb.com_maxscales.yaml b/config/crd/bases/k8s.mariadb.com_maxscales.yaml
index 7be2662a..c975fee5 100644
--- a/config/crd/bases/k8s.mariadb.com_maxscales.yaml
+++ b/config/crd/bases/k8s.mariadb.com_maxscales.yaml
@@ -1223,6 +1223,11 @@ spec:
                                 x-kubernetes-list-type: atomic
                             type: object
                         type: object
+                      args:
+                        description: Args to be used in the Container.
+                        items:
+                          type: string
+                        type: array
                       image:
                         description: |-
                           Image name to be used as metrics exporter. The supported format is `<image>:<tag>`.
diff --git a/deploy/charts/mariadb-operator-crds/templates/crds.yaml b/deploy/charts/mariadb-operator-crds/templates/crds.yaml
index 5aa25fe1..342628cf 100644
--- a/deploy/charts/mariadb-operator-crds/templates/crds.yaml
+++ b/deploy/charts/mariadb-operator-crds/templates/crds.yaml
@@ -4932,6 +4932,11 @@ spec:
                                     x-kubernetes-list-type: atomic
                                 type: object
                             type: object
+                          args:
+                            description: Args to be used in the Container.
+                            items:
+                              type: string
+                            type: array
                           image:
                             description: |-
                               Image name to be used as metrics exporter. The supported format is `<image>:<tag>`.
@@ -5758,6 +5763,11 @@ spec:
                                 x-kubernetes-list-type: atomic
                             type: object
                         type: object
+                      args:
+                        description: Args to be used in the Container.
+                        items:
+                          type: string
+                        type: array
                       image:
                         description: |-
                           Image name to be used as metrics exporter. The supported format is `<image>:<tag>`.
@@ -9004,6 +9014,11 @@ spec:
                                 x-kubernetes-list-type: atomic
                             type: object
                         type: object
+                      args:
+                        description: Args to be used in the Container.
+                        items:
+                          type: string
+                        type: array
                       image:
                         description: |-
                           Image name to be used as metrics exporter. The supported format is `<image>:<tag>`.
diff --git a/pkg/builder/deployment_builder.go b/pkg/builder/deployment_builder.go
index 7130ca39..03888222 100644
--- a/pkg/builder/deployment_builder.go
+++ b/pkg/builder/deployment_builder.go
@@ -259,6 +259,10 @@ func (b *Builder) exporterContainer(exporter *mariadbv1alpha1.Exporter, args []s
 		resources = exporter.Resources.ToKubernetesType()
 	}
 
+	if exporter.Args != nil {
+		args = append(args, exporter.Args...)
+	}
+
 	probe := &corev1.Probe{
 		ProbeHandler: corev1.ProbeHandler{
 			HTTPGet: &corev1.HTTPGetAction{



Test patch:
diff --git a/pkg/builder/deployment_builder_test.go b/pkg/builder/deployment_builder_test.go
index 461971e6..7a47dfec 100644
--- a/pkg/builder/deployment_builder_test.go
+++ b/pkg/builder/deployment_builder_test.go
@@ -858,3 +858,68 @@ func TestExporterVolumes(t *testing.T) {
 		})
 	}
 }
+
+func TestExporterArgs(t *testing.T) {
+	builder := newDefaultTestBuilder(t)
+	objMeta := metav1.ObjectMeta{
+		Name:      "mariadb-metrics-resources",
+		Namespace: "test",
+	}
+
+	tests := []struct {
+		name     string
+		mariadb  *mariadbv1alpha1.MariaDB
+		wantArgs []string
+	}{
+		{
+			name: "Without args",
+			mariadb: &mariadbv1alpha1.MariaDB{
+				ObjectMeta: objMeta,
+				Spec: mariadbv1alpha1.MariaDBSpec{
+					Metrics: &mariadbv1alpha1.MariadbMetrics{
+						Enabled: true,
+					},
+				},
+			},
+			wantArgs: []string{
+				"--config.my-cnf=/etc/config/exporter.cnf",
+			},
+		},
+		{
+			name: "With args",
+			mariadb: &mariadbv1alpha1.MariaDB{
+				ObjectMeta: objMeta,
+				Spec: mariadbv1alpha1.MariaDBSpec{
+					Metrics: &mariadbv1alpha1.MariadbMetrics{
+						Enabled: true,
+						Exporter: mariadbv1alpha1.Exporter{
+							Args: []string{
+								"--no-collect.auto_increment.columns",
+								"--collect.sys.user_summary",
+							},
+						},
+					},
+				},
+			},
+			wantArgs: []string{
+				"--config.my-cnf=/etc/config/exporter.cnf",
+				"--no-collect.auto_increment.columns",
+				"--collect.sys.user_summary",
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			deploy, err := builder.BuildExporterDeployment(tt.mariadb, nil)
+			if err != nil {
+				t.Fatalf("unexpected error building Deployment: %v", err)
+			}
+
+			args := deploy.Spec.Template.Spec.Containers[0].Args
+			if !reflect.DeepEqual(tt.wantArgs, args) {
+				t.Errorf("unexpected Args, want: %v got: %v", tt.wantArgs, args)
+			}
+		})
+	}
+}