diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a616e36..7570937 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,22 +31,22 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 with: persist-credentials: false - - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version-file: go.mod cache: false - name: Check approved Go release line run: go env GOVERSION | grep -Eq '^go1\.26\.[0-9]+$' - name: golangci-lint - uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0 + uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9.3.0 with: # Require: The version of golangci-lint to use. # When `install-mode` is `binary` (default) the value can be v1.2 or v1.2.3 or `latest` to use the latest version. # When `install-mode` is `goinstall` the value can be v1.2.3, `latest`, or the hash of a commit. - version: v2.11.3 + version: v2.14.0 check-license: name: License scan @@ -58,10 +58,10 @@ jobs: REPORT_FILE: gl-license-scanning-report.json steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 with: persist-credentials: false - - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version-file: go.mod cache: false @@ -73,7 +73,7 @@ jobs: run: | go-licenses report . > licenses.csv - name: Save license scan report - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: license_scanning path: licenses.csv @@ -86,15 +86,15 @@ jobs: contents: read steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 with: persist-credentials: false - - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version-file: go.mod cache: false - name: Run GoReleaser - uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7.2.2 + uses: goreleaser/goreleaser-action@a4f02ab5355a589de60d917a659ce617ed19b3de # v7.3.0 with: # either 'goreleaser' (default) or 'goreleaser-pro' distribution: goreleaser @@ -112,10 +112,10 @@ jobs: contents: read steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 with: persist-credentials: false - - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version-file: go.mod cache: false @@ -132,10 +132,10 @@ jobs: GOVULNCHECK_VERSION: v1.6.0 steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 with: persist-credentials: false - - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version-file: go.mod cache: false @@ -148,7 +148,7 @@ jobs: - name: Test that the symbol-table guard rejects a stripped binary run: scripts/assert-go-symbols-test.sh - name: Build GoReleaser snapshot artifacts - uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7.2.2 + uses: goreleaser/goreleaser-action@a4f02ab5355a589de60d917a659ce617ed19b3de # v7.3.0 with: distribution: goreleaser version: v1.25.1 @@ -169,7 +169,7 @@ jobs: upload-sarif: "false" - name: Upload security evidence if: always() - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: release-artifact-security path: | @@ -193,15 +193,15 @@ jobs: S3_BUCKET: "s3://cli-dl.stackstate.com/stackstate-backup-cli/" GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 with: persist-credentials: false - - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 + - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version-file: go.mod cache: false - name: Go releaser publish - uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7.2.2 + uses: goreleaser/goreleaser-action@a4f02ab5355a589de60d917a659ce617ed19b3de # v7.3.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} diff --git a/.github/workflows/renovate.yml b/.github/workflows/renovate.yml index bedbd55..5714142 100644 --- a/.github/workflows/renovate.yml +++ b/.github/workflows/renovate.yml @@ -39,7 +39,7 @@ jobs: permission-checks: read permission-statuses: read - name: Run Renovate - uses: renovatebot/github-action@8217b3fc286df088d7c27f3255fe8414463bc0fd # v46.1.15 + uses: renovatebot/github-action@f0f41e5f2e706165f6814b1d0f0d0e319de7d1d9 # v46.3.8 with: token: ${{ steps.app-token.outputs.token }} env: diff --git a/.golangci.yml b/.golangci.yml index 63f93a9..ca7a54c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -45,6 +45,8 @@ linters: funlen: lines: 100 statements: 60 + goconst: + ignore-tests: true lll: line-length: 250 mnd: diff --git a/cmd/settings/check_and_finalize.go b/cmd/settings/check_and_finalize.go index ced0ded..53e6f5c 100644 --- a/cmd/settings/check_and_finalize.go +++ b/cmd/settings/check_and_finalize.go @@ -47,7 +47,7 @@ func runCheckAndFinalize(appCtx *app.Context) error { K8sClient: appCtx.K8sClient, Namespace: appCtx.Namespace, JobName: checkJobName, - ServiceName: "settings", + ServiceName: settingsName, ScaleUpFn: scale.ScaleUpAndReleaseLock, ScaleDownFn: scale.ScaleDown, ScaleSelector: appCtx.Config.Settings.Restore.ScaleDownLabelSelector, diff --git a/cmd/settings/restore.go b/cmd/settings/restore.go index 86742b5..5b00e8c 100644 --- a/cmd/settings/restore.go +++ b/cmd/settings/restore.go @@ -309,7 +309,7 @@ func buildVolumes(config *config.Config, defaultMode int32) []corev1.Volume { // buildContainers constructs containers for the restore job func buildContainer(envVar []corev1.EnvVar, command []string, config *config.Config) corev1.Container { return corev1.Container{ - Name: "settings", + Name: settingsName, Image: config.Settings.Restore.Job.Image, ImagePullPolicy: corev1.PullIfNotPresent, SecurityContext: k8s.ConvertSecurityContext(config.Settings.Restore.Job.ContainerSecurityContext), diff --git a/cmd/settings/settings.go b/cmd/settings/settings.go index 6ed4702..0076ee9 100644 --- a/cmd/settings/settings.go +++ b/cmd/settings/settings.go @@ -5,9 +5,11 @@ import ( "github.com/stackvista/stackstate-backup-cli/internal/foundation/config" ) +const settingsName = config.DatastoreSettings + func Cmd(globalFlags *config.CLIGlobalFlags) *cobra.Command { cmd := &cobra.Command{ - Use: "settings", + Use: settingsName, Short: "Settings backup and restore operations", } diff --git a/cmd/stackgraphv2/restore.go b/cmd/stackgraphv2/restore.go index be2f1ab..9621ea6 100644 --- a/cmd/stackgraphv2/restore.go +++ b/cmd/stackgraphv2/restore.go @@ -26,6 +26,9 @@ const ( restoreNameTemplate = "stackgraph-v2-restore" configMapDefaultFileMode = 0755 purgeStackgraphDataFlag = "-force" + backupLogVolume = "backup-log" + restoreScriptsVolume = "backup-restore-scripts" + minioKeysVolume = "minio-keys" ) // Restore command flags @@ -306,9 +309,9 @@ func buildRestoreEnvVars(backupFile string, config *config.Config) []corev1.EnvV // buildRestoreVolumeMounts constructs volume mounts for the restore job container func buildRestoreVolumeMounts(config *config.Config) []corev1.VolumeMount { volumeMounts := []corev1.VolumeMount{ - {Name: "backup-log", MountPath: "/opt/docker/etc_log"}, - {Name: "backup-restore-scripts", MountPath: "/backup-restore-scripts"}, - {Name: "minio-keys", MountPath: "/aws-keys"}, + {Name: backupLogVolume, MountPath: "/opt/docker/etc_log"}, + {Name: restoreScriptsVolume, MountPath: "/backup-restore-scripts"}, + {Name: minioKeysVolume, MountPath: "/aws-keys"}, {Name: "tmp-data", MountPath: "/tmp-data"}, } @@ -344,7 +347,7 @@ func buildRestoreInitContainers(config *config.Config) []corev1.Container { func buildRestoreVolumes(jobName string, config *config.Config, defaultMode int32) []corev1.Volume { volumes := []corev1.Volume{ { - Name: "backup-log", + Name: backupLogVolume, VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ @@ -354,7 +357,7 @@ func buildRestoreVolumes(jobName string, config *config.Config, defaultMode int3 }, }, { - Name: "backup-restore-scripts", + Name: restoreScriptsVolume, VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ @@ -365,7 +368,7 @@ func buildRestoreVolumes(jobName string, config *config.Config, defaultMode int3 }, }, { - Name: "minio-keys", + Name: minioKeysVolume, VolumeSource: corev1.VolumeSource{ Secret: &corev1.SecretVolumeSource{ SecretName: restore.MinioKeysSecretName, diff --git a/cmd/stackgraphv2/simplejob.go b/cmd/stackgraphv2/simplejob.go index e6ca0e2..cb54baa 100644 --- a/cmd/stackgraphv2/simplejob.go +++ b/cmd/stackgraphv2/simplejob.go @@ -58,9 +58,9 @@ func buildSimpleJobEnvVars(config *config.Config) []corev1.EnvVar { // buildSimpleJobVolumeMounts constructs volume mounts shared by the abort and backfill job containers func buildSimpleJobVolumeMounts() []corev1.VolumeMount { return []corev1.VolumeMount{ - {Name: "backup-log", MountPath: "/opt/docker/etc_log"}, - {Name: "backup-restore-scripts", MountPath: "/backup-restore-scripts"}, - {Name: "minio-keys", MountPath: "/aws-keys"}, + {Name: backupLogVolume, MountPath: "/opt/docker/etc_log"}, + {Name: restoreScriptsVolume, MountPath: "/backup-restore-scripts"}, + {Name: minioKeysVolume, MountPath: "/aws-keys"}, } } @@ -86,7 +86,7 @@ func buildSimpleJobInitContainers(config *config.Config) []corev1.Container { func buildSimpleJobVolumes(config *config.Config, defaultMode int32) []corev1.Volume { return []corev1.Volume{ { - Name: "backup-log", + Name: backupLogVolume, VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ @@ -96,7 +96,7 @@ func buildSimpleJobVolumes(config *config.Config, defaultMode int32) []corev1.Vo }, }, { - Name: "backup-restore-scripts", + Name: restoreScriptsVolume, VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ @@ -107,7 +107,7 @@ func buildSimpleJobVolumes(config *config.Config, defaultMode int32) []corev1.Vo }, }, { - Name: "minio-keys", + Name: minioKeysVolume, VolumeSource: corev1.VolumeSource{ Secret: &corev1.SecretVolumeSource{ SecretName: restore.MinioKeysSecretName, diff --git a/internal/orchestration/replication/applicability.go b/internal/orchestration/replication/applicability.go index 8edc4bd..1d0ef2b 100644 --- a/internal/orchestration/replication/applicability.go +++ b/internal/orchestration/replication/applicability.go @@ -7,11 +7,14 @@ import ( ) const ( - hdfsComponent = "hdfs" - clickhouseComponent = "clickhouse" - nameNodeComponent = "hdfs-nn" - dataNodeComponent = "hdfs-dn" - monoComponent = "stackgraph" + hdfsComponent = "hdfs" + clickhouseComponent = "clickhouse" + elasticsearchComponent = "elasticsearch" + kafkaComponent = "kafka" + zookeeperComponent = "zookeeper" + nameNodeComponent = "hdfs-nn" + dataNodeComponent = "hdfs-dn" + monoComponent = "stackgraph" ) func workloadComponent(workload appsv1.StatefulSet) string { @@ -26,7 +29,7 @@ func workloadComponent(workload appsv1.StatefulSet) string { } } switch name { - case "elasticsearch", clickhouseComponent, "kafka", "zookeeper": + case elasticsearchComponent, clickhouseComponent, kafkaComponent, zookeeperComponent: return name default: return "" diff --git a/internal/orchestration/replication/checker.go b/internal/orchestration/replication/checker.go index 538039d..19fb759 100644 --- a/internal/orchestration/replication/checker.go +++ b/internal/orchestration/replication/checker.go @@ -6,7 +6,12 @@ import ( "time" ) -const requestTimeout = 30 * time.Second +const ( + requestTimeout = 30 * time.Second + bashBinary = "bash" + bashFlags = "-ec" + replicationQueryName = "replication-check" +) // Checker observes databases without invoking backup or restore operations. type Checker struct { @@ -83,15 +88,15 @@ func (c *Checker) query(ctx context.Context, pod, container string, command []st func (c *Checker) checkComponent(ctx context.Context, inventory inventory, component string) Result { switch component { - case "hdfs": + case hdfsComponent: return c.checkHDFS(ctx, inventory) - case "elasticsearch": + case elasticsearchComponent: return c.checkElasticsearch(ctx, inventory) - case "kafka": + case kafkaComponent: return c.checkKafka(ctx, inventory) - case "clickhouse": + case clickhouseComponent: return c.checkClickHouse(ctx, inventory) - case "zookeeper": + case zookeeperComponent: return c.checkZooKeeper(ctx, inventory) default: return result(component, Unknown, "unsupported component") diff --git a/internal/orchestration/replication/clickhouse.go b/internal/orchestration/replication/clickhouse.go index f520882..d9697f9 100644 --- a/internal/orchestration/replication/clickhouse.go +++ b/internal/orchestration/replication/clickhouse.go @@ -45,7 +45,7 @@ func (c *Checker) checkClickHouse(ctx context.Context, inventory inventory) Resu if member.replicas < minReplicas { return result("clickhouse", Degraded, fmt.Sprintf("%s belongs to a shard with fewer than two replicas", member.pod.Name)) } - command := []string{"bash", "-ec", clickhouseQuery, "replication-check", clickhouseSQL} + command := []string{bashBinary, bashFlags, clickhouseQuery, replicationQueryName, clickhouseSQL} data, err := c.query(ctx, member.pod.Name, "clickhouse", command) if err != nil { return result("clickhouse", Unknown, err.Error()) @@ -67,7 +67,7 @@ func (c *Checker) verifyEmptyLogs(ctx context.Context, pod string, rows []replic if !rows[n].needsLogVerification { continue } - command := []string{"bash", "-ec", clickhouseQuery, "replication-check", clickhouseEmptyLogSQL, "--param_log_path=" + rows[n].path + "/log"} + command := []string{bashBinary, bashFlags, clickhouseQuery, replicationQueryName, clickhouseEmptyLogSQL, "--param_log_path=" + rows[n].path + "/log"} data, err := c.query(ctx, pod, "clickhouse", command) if err != nil { return fmt.Errorf("%s: could not verify empty replication log: %w", pod, err) @@ -178,7 +178,7 @@ func evaluateClickHouse(observations []replicaObservation) Result { } if len(problems) > 0 { sort.Strings(problems) - return Result{Component: "clickhouse", Status: Degraded, Messages: problems} + return Result{Component: clickhouseComponent, Status: Degraded, Messages: problems} } report := result("clickhouse", Healthy, fmt.Sprintf("%d replicated table groups checked on every member; no pending data replication tasks", len(groups))) if historicalErrors > 0 { diff --git a/internal/orchestration/replication/elasticsearch.go b/internal/orchestration/replication/elasticsearch.go index 0bf0c86..f74cc65 100644 --- a/internal/orchestration/replication/elasticsearch.go +++ b/internal/orchestration/replication/elasticsearch.go @@ -21,7 +21,7 @@ func (c *Checker) checkElasticsearch(ctx context.Context, inventory inventory) R if err := expectedMembers(members); err != nil { return result("elasticsearch", Degraded, err.Error()) } - command := []string{"bash", "-ec", elasticsearchQuery} + command := []string{bashBinary, bashFlags, elasticsearchQuery} data, err := c.query(ctx, members[0].pod.Name, "elasticsearch", command) if err != nil { return result("elasticsearch", Unknown, err.Error()) @@ -66,7 +66,7 @@ func evaluateElasticsearch(data []byte, expected int) Result { } if len(problems) > 0 { sort.Strings(problems) - return Result{Component: "elasticsearch", Status: Degraded, Messages: problems} + return Result{Component: elasticsearchComponent, Status: Degraded, Messages: problems} } return result("elasticsearch", Healthy, fmt.Sprintf("%d indices have replica shards; all shards allocated with no recovery or relocation", len(indices))) } diff --git a/internal/orchestration/replication/hdfs.go b/internal/orchestration/replication/hdfs.go index ab18cce..ce9fed4 100644 --- a/internal/orchestration/replication/hdfs.go +++ b/internal/orchestration/replication/hdfs.go @@ -30,7 +30,7 @@ func (c *Checker) checkHDFS(ctx context.Context, inventory inventory) Result { if err := expectedMembers(datanodes); err != nil { return result("hdfs", Degraded, err.Error()) } - data, err := c.query(ctx, namenodes[0].pod.Name, "namenode", []string{"bash", "-ec", hdfsQuery}) + data, err := c.query(ctx, namenodes[0].pod.Name, "namenode", []string{bashBinary, bashFlags, hdfsQuery}) if err != nil { return result("hdfs", Unknown, err.Error()) } @@ -85,7 +85,7 @@ func evaluateHDFS(data []byte, expected int) Result { } } if len(problems) > 0 { - return Result{Component: "hdfs", Status: Degraded, Messages: problems} + return Result{Component: hdfsComponent, Status: Degraded, Messages: problems} } return result("hdfs", Healthy, fmt.Sprintf("%d DataNodes live; no missing, corrupt, under-replicated or pending-replication blocks", expected)) } diff --git a/internal/orchestration/replication/hdfs_audit.go b/internal/orchestration/replication/hdfs_audit.go index c56038f..a2c105e 100644 --- a/internal/orchestration/replication/hdfs_audit.go +++ b/internal/orchestration/replication/hdfs_audit.go @@ -49,7 +49,7 @@ func (c *Checker) Verify(ctx context.Context, previous Report) Report { func (c *Checker) auditHDFS(ctx context.Context, pod string) Result { parser := &fsckParser{} - err := c.kube.ExecTo(ctx, c.options.Namespace, pod, "namenode", []string{"bash", "-ec", hdfsAuditQuery}, parser) + err := c.kube.ExecTo(ctx, c.options.Namespace, pod, "namenode", []string{bashBinary, bashFlags, hdfsAuditQuery}, parser) if ctx.Err() != nil { return result(hdfsComponent, Unknown, fmt.Sprintf("HDFS block audit did not complete: %v", ctx.Err())) } diff --git a/internal/orchestration/replication/hdfs_fsck.go b/internal/orchestration/replication/hdfs_fsck.go index e6ead1d..aa2aa1c 100644 --- a/internal/orchestration/replication/hdfs_fsck.go +++ b/internal/orchestration/replication/hdfs_fsck.go @@ -93,7 +93,7 @@ func (p *fsckParser) result() Result { return result("hdfs", Unknown, "incomplete fsck report; block replication could not be verified") } if p.problems > 0 { - return Result{Component: "hdfs", Status: Degraded, + return Result{Component: hdfsComponent, Status: Degraded, Messages: append([]string{fmt.Sprintf("HDFS block audit found %d replication problems", p.problems)}, p.messages...)} } report := result("hdfs", Healthy, fmt.Sprintf("HDFS audit: %d files and %d completed block entries meet replication targets of at least two (including snapshot references)", p.files, p.completed)) diff --git a/internal/orchestration/replication/kafka.go b/internal/orchestration/replication/kafka.go index 4887404..64a607c 100644 --- a/internal/orchestration/replication/kafka.go +++ b/internal/orchestration/replication/kafka.go @@ -39,7 +39,7 @@ func (c *Checker) checkKafka(ctx context.Context, inventory inventory) Result { if err := expectedMembers(members); err != nil { return result("kafka", Degraded, err.Error()) } - command := []string{"bash", "-ec", kafkaQuery, "replication-check", "--bootstrap-server", "localhost:9092", "--describe"} + command := []string{bashBinary, bashFlags, kafkaQuery, replicationQueryName, "--bootstrap-server", "localhost:9092", "--describe"} data, err := c.query(ctx, members[0].pod.Name, "kafka", command) if err != nil { return result("kafka", Unknown, err.Error()) @@ -48,7 +48,7 @@ func (c *Checker) checkKafka(ctx context.Context, inventory inventory) Result { if report.Status == Unknown || hasTransactionTopic(string(data)) { return report } - probe := []string{"bash", "-ec", transactionTopicQuery, "replication-check", "--bootstrap-server", "localhost:9092"} + probe := []string{bashBinary, bashFlags, transactionTopicQuery, replicationQueryName, "--bootstrap-server", "localhost:9092"} presence, err := c.query(ctx, members[0].pod.Name, "kafka", probe) if err != nil || strings.TrimSpace(string(presence)) != "absent" { report.Status = Unknown @@ -144,7 +144,7 @@ func evaluateKafka(output string) Result { } report := result("kafka", Healthy, fmt.Sprintf("all partitions of %d topics have at least two replicas, complete ISR and an in-sync leader", len(counts))) if len(problems) > 0 { - report = Result{Component: "kafka", Status: Degraded, Messages: problems} + report = Result{Component: kafkaComponent, Status: Degraded, Messages: problems} } return report } diff --git a/internal/orchestration/replication/report.go b/internal/orchestration/replication/report.go index c6ee113..50acf89 100644 --- a/internal/orchestration/replication/report.go +++ b/internal/orchestration/replication/report.go @@ -17,7 +17,7 @@ const ( minReplicas = 2 ) -var supportedComponents = []string{"hdfs", "elasticsearch", "kafka", "clickhouse", "zookeeper"} +var supportedComponents = []string{hdfsComponent, elasticsearchComponent, kafkaComponent, clickhouseComponent, zookeeperComponent} // Options identifies the installation and selected databases. type Options struct { diff --git a/internal/orchestration/replication/zookeeper.go b/internal/orchestration/replication/zookeeper.go index f04478d..ff82ac0 100644 --- a/internal/orchestration/replication/zookeeper.go +++ b/internal/orchestration/replication/zookeeper.go @@ -76,7 +76,7 @@ func (c *Checker) checkZooKeeper(ctx context.Context, inventory inventory) Resul } func (c *Checker) queryZooKeeper(ctx context.Context, pod string) (zooKeeperObservation, error) { - data, err := c.query(ctx, pod, "zookeeper", []string{"bash", "-ec", zookeeperQuery}) + data, err := c.query(ctx, pod, "zookeeper", []string{bashBinary, bashFlags, zookeeperQuery}) if err != nil { return zooKeeperObservation{}, err } @@ -163,7 +163,7 @@ func evaluateZooKeeper(observations []zooKeeperObservation) Result { problems = append(problems, fmt.Sprintf("expected one ZooKeeper leader; observed %d", leaders)) } if len(problems) > 0 { - return Result{Component: "zookeeper", Status: Degraded, Messages: problems} + return Result{Component: zookeeperComponent, Status: Degraded, Messages: problems} } return result("zookeeper", Healthy, fmt.Sprintf("%d voting members available; one leader and %d synchronized followers", len(observations), len(observations)-1)) }