Repository: ClusterLabs/ha_cluster_exporter (go)

Issue:
sbd data is not exported if devices in SBD_DEVICE have an space after ;
sbd data is not exported if devices in SBD_DEVICE have an space after `;`.

This setup works for sbd.

Here an example (check the space after the `;`):
```
SBD_DEVICE="/dev/disk/by-id/scsi-SLIO-ORG_IBLOCK_8071fac5-f560-4c78-b1fb-77ca7c86ebd5; /dev/disk/by-id/scsi-SLIO-ORG_IBLOCK_7eab20b6-1755-400a-8a41-d191dfe2e09b"
```

We would need to change the regular expression in https://github.com/ClusterLabs/ha_cluster_exporter/blob/master/collector/sbd/sbd.go#L116 to catch this scenario too, as it is allowed by sbd

Pull request description:
make sbd config devices parser more resilient
fixes #197 

Patch:
diff --git a/.editorconfig b/.editorconfig
index 5400916..52acbc6 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -8,4 +8,7 @@ insert_final_newline = true
 indent_size = 2
 
 [Makefile]
+indent_style = tab
+
+[*.go]
 indent_style = tab
\ No newline at end of file
diff --git a/collector/sbd/sbd.go b/collector/sbd/sbd.go
index 476f5c0..0734b37 100644
--- a/collector/sbd/sbd.go
+++ b/collector/sbd/sbd.go
@@ -116,7 +116,7 @@ func getSbdDevices(sbdConfigRaw []byte) []string {
 	// Unbalanced double quotes are not checked and they will still produce a match
 	// If multiple matching lines are present, only the first will be used
 	// The single device name pattern is `[\w-/]+`, which is pretty relaxed
-	regex := regexp.MustCompile(`(?m)^\s*SBD_DEVICE="?((?:[\w-/]+;?)+)"?\s*$`)
+	regex := regexp.MustCompile(`(?m)^\s*SBD_DEVICE="?((?:[\w-/]+;?\s?)+)"?\s*$`)
 	sbdDevicesLine := regex.FindStringSubmatch(string(sbdConfigRaw))
 
 	// if SBD_DEVICE line could not be found, return 0 devices
@@ -125,7 +125,10 @@ func getSbdDevices(sbdConfigRaw []byte) []string {
 	}
 
 	// split the first capture group, e.g. `/dev/foo;/dev/bar`; the 0th element is always the whole line
-	sbdDevices := strings.Split(sbdDevicesLine[1], ";")
+	sbdDevices := strings.Split(strings.TrimRight(sbdDevicesLine[1], ";"), ";")
+	for i, _ := range sbdDevices {
+		sbdDevices[i] = strings.TrimSpace(sbdDevices[i])
+	}
 
 	return sbdDevices
 }


Test patch:
diff --git a/collector/sbd/sbd_test.go b/collector/sbd/sbd_test.go
index b41a1de..a1ebfe2 100644
--- a/collector/sbd/sbd_test.go
+++ b/collector/sbd/sbd_test.go
@@ -187,6 +187,26 @@ SBD_DEVICE=/dev/vdc;/dev/vdd`
 	assert.Equal(t, "/dev/vdd", sbdDevices[1])
 }
 
+func TestSbdDeviceParserWithSpaceAfterSemicolon(t *testing.T) {
+	sbdConfig := `SBD_DEVICE=/dev/vdc; /dev/vdd`
+
+	sbdDevices := getSbdDevices([]byte(sbdConfig))
+
+	assert.Len(t, sbdDevices, 2)
+	assert.Equal(t, "/dev/vdc", sbdDevices[0])
+	assert.Equal(t, "/dev/vdd", sbdDevices[1])
+}
+
+func TestSbdDeviceParserWithSemicolon(t *testing.T) {
+	sbdConfig := `SBD_DEVICE=/dev/vdc;/dev/vdd;`
+
+	sbdDevices := getSbdDevices([]byte(sbdConfig))
+
+	assert.Len(t, sbdDevices, 2)
+	assert.Equal(t, "/dev/vdc", sbdDevices[0])
+	assert.Equal(t, "/dev/vdd", sbdDevices[1])
+}
+
 func TestNewSbdCollector(t *testing.T) {
 	_, err := NewCollector("../../test/fake_sbd.sh", "../../test/fake_sbdconfig", false, log.NewNopLogger())