Skip to content

Commit

Permalink
adding version check
Browse files Browse the repository at this point in the history
  • Loading branch information
josephbarnett committed Jul 15, 2024
1 parent 90dd727 commit fa0236f
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 0 deletions.
108 changes: 108 additions & 0 deletions pkg/diagnostic/prom/version/check.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package version

import (
"bytes"
"context"
"fmt"
net "net/http"
"os"
"os/exec"

"github.com/cloudzero/cloudzero-agent-validator/pkg/config"
"github.com/cloudzero/cloudzero-agent-validator/pkg/diagnostic"
"github.com/cloudzero/cloudzero-agent-validator/pkg/logging"
"github.com/cloudzero/cloudzero-agent-validator/pkg/status"
"github.com/sirupsen/logrus"
)

const DiagnosticPrometheusVersion = config.DiagnosticPrometheusVersion

type checker struct {
cfg *config.Settings
logger *logrus.Entry
}

func NewProvider(ctx context.Context, cfg *config.Settings) diagnostic.Provider {
return &checker{
cfg: cfg,
logger: logging.NewLogger().
WithContext(ctx).WithField(logging.OpField, "prom"),
}
}

func (c *checker) Check(ctx context.Context, _ *net.Client, accessor status.Accessor) error {
if len(c.cfg.Prometheus.Executable) == 0 {
accessor.AddCheck(&status.StatusCheck{
Name: DiagnosticPrometheusVersion,
Error: "no prometheus binary available at configured location",
})
return nil
}

versionData, err := c.GetVersion(ctx)
if err != nil {
accessor.AddCheck(
&status.StatusCheck{
Name: DiagnosticPrometheusVersion,
Error: err.Error(),
})
return nil
}

accessor.WriteToReport(func(s *status.ClusterStatus) {
s.AgentVersion = string(versionData)
s.Checks = append(s.Checks, &status.StatusCheck{Name: DiagnosticPrometheusVersion, Passing: true})
})
return nil
}

func (c *checker) GetVersion(ctx context.Context) ([]byte, error) {
executable := c.cfg.Prometheus.Executable
if len(executable) == 0 {
return nil, fmt.Errorf("no prometheus binary available at configured location")
}

fi, err := os.Stat(executable)
if os.IsNotExist(err) {
return nil, fmt.Errorf("prometheus executable not found: %w", err)
}
if fi.Mode()&0111 == 0 {
return nil, fmt.Errorf("prometheus executable is not executable: %s", executable)
}

// create the raw output fle
rawOutput, err := os.CreateTemp(os.TempDir(), ".promver.*")
if err != nil {
return nil, fmt.Errorf("failed to create raw prometheus version output file: %w", err)
}
defer func() {
_ = rawOutput.Close()
_ = os.Remove(rawOutput.Name())
}()

// Build the command and Exec the scanner
cmd := exec.CommandContext(ctx, executable, "--version")

// capture the output
var stderr bytes.Buffer
cmd.Stderr = &stderr
cmd.Stdout = rawOutput

// Now run the app
if err := cmd.Run(); err != nil {
return nil, fmt.Errorf("failed to run prometheus: %w", err)
}

// make sure all bytes are written from the standard output
if err := rawOutput.Sync(); err != nil {
return nil, fmt.Errorf("failed to sync raw prometheus output file: %w", err)
}

// seek to the beginning of the file for reading.
if _, err := rawOutput.Seek(0, 0); err != nil {
return nil, fmt.Errorf("failed to seek to the beginning of the raw prometheus output file: %w", err)
}

// read the results into a byte slice
return os.ReadFile(rawOutput.Name())
}
74 changes: 74 additions & 0 deletions pkg/diagnostic/prom/version/check_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package version_test

import (
"context"
"os"
"testing"

"github.com/stretchr/testify/assert"

"github.com/cloudzero/cloudzero-agent-validator/pkg/config"
"github.com/cloudzero/cloudzero-agent-validator/pkg/diagnostic/prom/version"
"github.com/cloudzero/cloudzero-agent-validator/pkg/status"
)

func makeReport() status.Accessor {
return status.NewAccessor(&status.ClusterStatus{})
}

func TestChecker_GetVersion(t *testing.T) {
tests := []struct {
name string
executable string
expected bool
}{
{
name: "ExecutableNotFound",
executable: "/path/to/nonexistent/prometheus",
expected: false,
},
{
name: "ExecutableEmpty",
executable: "",
expected: false,
},
{
name: "Success",
executable: getPromExecutablePath(),
expected: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cfg := &config.Settings{
Prometheus: config.Prometheus{
Executable: tt.executable,
},
}
provider := version.NewProvider(context.Background(), cfg)
accessor := makeReport()

err := provider.Check(context.Background(), nil, accessor)
assert.NoError(t, err)

accessor.ReadFromReport(func(s *status.ClusterStatus) {
assert.Len(t, s.Checks, 1)
for _, c := range s.Checks {
assert.Equal(t, tt.expected, c.Passing)
}
if tt.expected {
assert.NotEmpty(t, s.AgentVersion)
}
})
})
}
}

func getPromExecutablePath() string {
wd, err := os.Getwd()
if err != nil {
panic(err)
}
return wd + "/testdata/prometheus"
}
8 changes: 8 additions & 0 deletions pkg/diagnostic/prom/version/testdata/prometheus
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh

echo " prometheus, version 2.50.1 (branch: HEAD, revision: 8c9b0285360a0b6288d76214a75ce3025bce4050)"
echo " build user: root@6213bb3ee580"
echo " build date: 20240226-11:38:47"
echo " go version: go1.21.7"
echo " platform: linux/arm64"
echo " tags: netgo,builtinassets,stringlabels"

0 comments on commit fa0236f

Please sign in to comment.