-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
90dd727
commit fa0236f
Showing
3 changed files
with
190 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" |