-
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.
Merge pull request #12 from Cloudzero/CP-20097-capture-version-in-val…
…idator CP-20097 add prometheus version check
- Loading branch information
Showing
13 changed files
with
213 additions
and
17 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
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
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
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
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
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
2 changes: 1 addition & 1 deletion
2
pkg/diagnostic/prom/check.go → pkg/diagnostic/prom/config/check.go
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 |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package prom | ||
package config | ||
|
||
import ( | ||
"context" | ||
|
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
File renamed without changes.
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" |
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