Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Customize node exporter target #356

Merged
merged 5 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,16 @@ func LoadConfig(fileSystem afero.Fs) (*agent.Config, error) {
DiscoveriesPeriodsConfig: discoveryPeriodsConfig,
}

prometheusTargets := discovery.PrometheusTargets{
discovery.NodeExporterName: viper.GetString("node-exporter-target"),
}

return &agent.Config{
AgentID: agentID,
InstanceName: hostname,
DiscoveriesConfig: discoveriesConfig,
FactsServiceURL: viper.GetString("facts-service-url"),
PluginsFolder: viper.GetString("plugins-folder"),
PrometheusTargets: prometheusTargets,
}, nil
}
5 changes: 5 additions & 0 deletions cmd/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ func (suite *AgentCmdTestSuite) SetupTest() {
},
FactsServiceURL: "amqp://guest:guest@serviceurl:5672",
PluginsFolder: "/usr/etc/trento/plugins/",
PrometheusTargets: map[string]string{
"node_exporter": "10.0.0.5:9100",
},
}
}

Expand All @@ -85,6 +88,7 @@ func (suite *AgentCmdTestSuite) TestConfigFromFlags() {
"--api-key=some-api-key",
"--force-agent-id=some-agent-id",
"--facts-service-url=amqp://guest:guest@serviceurl:5672",
"--node-exporter-target=10.0.0.5:9100",
})

_ = suite.cmd.Execute()
Expand All @@ -107,6 +111,7 @@ func (suite *AgentCmdTestSuite) TestConfigFromEnv() {
os.Setenv("TRENTO_API_KEY", "some-api-key")
os.Setenv("TRENTO_FORCE_AGENT_ID", "some-agent-id")
os.Setenv("TRENTO_FACTS_SERVICE_URL", "amqp://guest:guest@serviceurl:5672")
os.Setenv("TRENTO_NODE_EXPORTER_TARGET", "10.0.0.5:9100")

_ = suite.cmd.Execute()

Expand Down
8 changes: 8 additions & 0 deletions cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,14 @@ func NewStartCmd() *cobra.Command {

startCmd.Flags().String("facts-service-url", "amqp://guest:guest@localhost:5672", "Facts service queue url")

startCmd.Flags().
String(
"node-exporter-target",
"",
"Node exporter target address in ip:port notation. If not given the lowest "+
"ipv4 address with the default 9100 port is used",
)

return startCmd
}

Expand Down
3 changes: 2 additions & 1 deletion internal/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type Config struct {
DiscoveriesConfig *discovery.DiscoveriesConfig
FactsServiceURL string
PluginsFolder string
PrometheusTargets discovery.PrometheusTargets
}

// NewAgent returns a new instance of Agent with the given configuration
Expand All @@ -48,7 +49,7 @@ func NewAgent(config *Config) (*Agent, error) {
discovery.NewSAPSystemsDiscovery(collectorClient, *config.DiscoveriesConfig),
discovery.NewCloudDiscovery(collectorClient, *config.DiscoveriesConfig),
discovery.NewSubscriptionDiscovery(collectorClient, config.InstanceName, *config.DiscoveriesConfig),
discovery.NewHostDiscovery(collectorClient, config.InstanceName, *config.DiscoveriesConfig),
discovery.NewHostDiscovery(collectorClient, config.InstanceName, config.PrometheusTargets, *config.DiscoveriesConfig),
discovery.NewSaptuneDiscovery(collectorClient, *config.DiscoveriesConfig),
}

Expand Down
21 changes: 11 additions & 10 deletions internal/core/hosts/discovered_host.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package hosts

type DiscoveredHost struct {
OSVersion string `json:"os_version"`
HostIPAddresses []string `json:"ip_addresses"`
Netmasks []int `json:"netmasks"`
HostName string `json:"hostname"`
CPUCount int `json:"cpu_count"`
SocketCount int `json:"socket_count"`
TotalMemoryMB int `json:"total_memory_mb"`
AgentVersion string `json:"agent_version"`
InstallationSource string `json:"installation_source"`
FullyQualifiedDomainName *string `json:"fully_qualified_domain_name,omitempty"`
OSVersion string `json:"os_version"`
HostIPAddresses []string `json:"ip_addresses"`
Netmasks []int `json:"netmasks"`
HostName string `json:"hostname"`
CPUCount int `json:"cpu_count"`
SocketCount int `json:"socket_count"`
TotalMemoryMB int `json:"total_memory_mb"`
AgentVersion string `json:"agent_version"`
InstallationSource string `json:"installation_source"`
FullyQualifiedDomainName *string `json:"fully_qualified_domain_name,omitempty"`
PrometheusTargets map[string]string `json:"prometheus_targets"`
}
57 changes: 49 additions & 8 deletions internal/discovery/host.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package discovery

import (
"bytes"
"context"
"fmt"
"net"
"slices"
"strconv"
"time"

Expand All @@ -20,23 +22,31 @@ import (
const HostDiscoveryID string = "host_discovery"
const HostDiscoveryMinPeriod time.Duration = 1 * time.Second

const NodeExporterName string = "node_exporter"
const NodeExporterPort int = 9100

type PrometheusTargets map[string]string

type HostDiscovery struct {
id string
collectorClient collector.Client
host string
interval time.Duration
id string
collectorClient collector.Client
host string
prometheusTargets PrometheusTargets
interval time.Duration
}

func NewHostDiscovery(
collectorClient collector.Client,
hostname string,
prometheusTargets PrometheusTargets,
config DiscoveriesConfig,
) Discovery {
return HostDiscovery{
id: HostDiscoveryID,
collectorClient: collectorClient,
host: hostname,
interval: config.DiscoveriesPeriodsConfig.Host,
id: HostDiscoveryID,
collectorClient: collectorClient,
host: hostname,
prometheusTargets: prometheusTargets,
interval: config.DiscoveriesPeriodsConfig.Host,
}
}

Expand All @@ -55,6 +65,8 @@ func (d HostDiscovery) Discover(ctx context.Context) (string, error) {
return "", err
}

updatedPrometheusTargets := updatePrometheusTargets(d.prometheusTargets, ipAddresses)

host := hosts.DiscoveredHost{
OSVersion: getOSVersion(),
HostIPAddresses: ipAddresses,
Expand All @@ -66,6 +78,7 @@ func (d HostDiscovery) Discover(ctx context.Context) (string, error) {
AgentVersion: version.Version,
InstallationSource: version.InstallationSource,
FullyQualifiedDomainName: getHostFQDN(),
PrometheusTargets: updatedPrometheusTargets,
}

err = d.collectorClient.Publish(ctx, d.id, host)
Expand Down Expand Up @@ -107,6 +120,34 @@ func getNetworksData() ([]string, []int, error) {
return ipAddrList, netmasks, nil
}

func updatePrometheusTargets(targets PrometheusTargets, ipAddresses []string) PrometheusTargets {
// Return exporter details if they are given by the user
nodeExporterTarget, ok := targets[NodeExporterName]
if ok && nodeExporterTarget != "" {
return PrometheusTargets{
NodeExporterName: nodeExporterTarget,
}
}

// Fallback to lowest IP address value to replace empty exporter targets
ips := make([]net.IP, 0, len(ipAddresses))
for _, ip := range ipAddresses {
parsedIP := net.ParseIP(ip)
if parsedIP.To4() != nil && !parsedIP.IsLoopback() {
ips = append(ips, parsedIP)
}

}

slices.SortFunc(ips, func(a, b net.IP) int {
return bytes.Compare(a, b)
})

return PrometheusTargets{
NodeExporterName: fmt.Sprintf("%s:%d", ips[0], NodeExporterPort),
}
}

func getHostFQDN() *string {

fqdn, err := fqdn.FqdnHostname()
Expand Down
42 changes: 42 additions & 0 deletions internal/discovery/host_internal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package discovery

import (
"testing"

"github.com/stretchr/testify/suite"
)

type HostInternalTestSuite struct {
suite.Suite
ipAddresses []string
}

func TestHostInternalTestSuite(t *testing.T) {
suite.Run(t, new(HostInternalTestSuite))
}

func (suite *HostInternalTestSuite) SetupSuite() {
suite.ipAddresses = []string{"127.0.0.1", "::1", "10.1.1.5", "10.1.1.4", "10.1.1.6", "6c62:7cc9:3936:e802:2bbe"}
}

func (suite *HostInternalTestSuite) TestUpdatePrometheusTargets() {
initialTargets := PrometheusTargets{
"node_exporter": "",
}

expectedTargets := PrometheusTargets{
"node_exporter": "10.1.1.4:9100",
}

updatedTargets := updatePrometheusTargets(initialTargets, suite.ipAddresses)
suite.Equal(expectedTargets, updatedTargets)
}

func (suite *HostInternalTestSuite) TestUpdatePrometheusTargetsGivenByUser() {
initialTargets := PrometheusTargets{
"node_exporter": "192.168.1.60:9123",
}

updatedTargets := updatePrometheusTargets(initialTargets, suite.ipAddresses)
suite.Equal(initialTargets, updatedTargets)
}
3 changes: 3 additions & 0 deletions internal/discovery/mocks/discovered_host_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,8 @@ func NewDiscoveredHostMock() hosts.DiscoveredHost {
AgentVersion: "trento-agent-version",
InstallationSource: "Community",
FullyQualifiedDomainName: &fqdn,
PrometheusTargets: map[string]string{
"node_exporter": "10.1.1.4:9100",
},
}
}
10 changes: 9 additions & 1 deletion packaging/config/agent.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,12 @@

## Facts gathering service URL

# facts-service-url: amqp://guest:guest@localhost:5672
# facts-service-url: amqp://guest:guest@localhost:5672

###############################################################################

## Prometheus exporters targets
## Configure the prometheus targets. If not given, the lowest discovered IP address
## with a default port number is used

# node-exporter-target: 192.168.1.10:9100
1 change: 1 addition & 0 deletions test/fixtures/config/agent.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ server-url: http://serverurl
api-key: some-api-key
force-agent-id: some-agent-id
facts-service-url: amqp://guest:guest@serviceurl:5672
node-exporter-target: 10.0.0.5:9100
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
"total_memory_mb": 4096,
"agent_version": "trento-agent-version",
"installation_source": "Community",
"fully_qualified_domain_name": "com.example.trento.host"
"fully_qualified_domain_name": "com.example.trento.host",
"prometheus_targets": {
"node_exporter": "10.1.1.4:9100"
}
}
}
Loading