Skip to content

Commit

Permalink
[ha-agent] Add haagent component (#30910)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandreYang authored Nov 21, 2024
1 parent efa45af commit a166214
Show file tree
Hide file tree
Showing 13 changed files with 320 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@
/comp/trace/etwtracer @DataDog/windows-agent
/comp/autoscaling/datadogclient @DataDog/container-integrations
/comp/etw @DataDog/windows-agent
/comp/haagent @DataDog/ndm-core
/comp/languagedetection/client @DataDog/container-platform
/comp/rdnsquerier @DataDog/ndm-integrations
/comp/serializer/compression @DataDog/agent-metrics-logs
Expand Down
2 changes: 2 additions & 0 deletions cmd/agent/subcommands/run/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
internalsettings "github.com/DataDog/datadog-agent/cmd/agent/subcommands/run/internal/settings"
agenttelemetry "github.com/DataDog/datadog-agent/comp/core/agenttelemetry/def"
agenttelemetryfx "github.com/DataDog/datadog-agent/comp/core/agenttelemetry/fx"
haagentfx "github.com/DataDog/datadog-agent/comp/haagent/fx"

// checks implemented as components

Expand Down Expand Up @@ -472,6 +473,7 @@ func getSharedFxOption() fx.Option {
agenttelemetryfx.Module(),
networkpath.Bundle(),
remoteagentregistryfx.Module(),
haagentfx.Module(),
)
}

Expand Down
6 changes: 6 additions & 0 deletions comp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,12 @@ Package datadogclient provides a client to query the datadog API

Package etw provides an ETW tracing interface

### [comp/haagent](https://pkg.go.dev/github.com/DataDog/datadog-agent/comp/haagent)

*Datadog Team*: ndm-core

Package haagent handles states for HA Agent feature.

### [comp/languagedetection/client](https://pkg.go.dev/github.com/DataDog/datadog-agent/comp/languagedetection/client)

*Datadog Team*: container-platform
Expand Down
25 changes: 25 additions & 0 deletions comp/haagent/def/component.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2024-present Datadog, Inc.

// Package haagent handles states for HA Agent feature.
package haagent

// team: ndm-core

// Component is the component type.
type Component interface {
// Enabled returns true if ha_agent.enabled is set to true
Enabled() bool

// GetGroup returns the value of ha_agent.group
GetGroup() string

// IsLeader returns true if the current Agent is leader
IsLeader() bool

// SetLeader takes the leader agent hostname as input, if it matches the current agent hostname,
// the isLeader state is set to true, otherwise false.
SetLeader(leaderAgentHostname string)
}
23 changes: 23 additions & 0 deletions comp/haagent/fx/fx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2024-present Datadog, Inc.

// Package fx provides the fx module for the haagent component
package fx

import (
haagent "github.com/DataDog/datadog-agent/comp/haagent/def"
haagentimpl "github.com/DataDog/datadog-agent/comp/haagent/impl"
"github.com/DataDog/datadog-agent/pkg/util/fxutil"
)

// Module defines the fx options for this component
func Module() fxutil.Module {
return fxutil.Component(
fxutil.ProvideComponentConstructor(
haagentimpl.NewComponent,
),
fxutil.ProvideOptional[haagent.Component](),
)
}
22 changes: 22 additions & 0 deletions comp/haagent/impl/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2024-present Datadog, Inc.

package haagentimpl

import (
"github.com/DataDog/datadog-agent/comp/core/config"
)

type haAgentConfigs struct {
enabled bool
group string
}

func newHaAgentConfigs(agentConfig config.Component) *haAgentConfigs {
return &haAgentConfigs{
enabled: agentConfig.GetBool("ha_agent.enabled"),
group: agentConfig.GetString("ha_agent.group"),
}
}
49 changes: 49 additions & 0 deletions comp/haagent/impl/haagent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2024-present Datadog, Inc.

package haagentimpl

import (
"context"

log "github.com/DataDog/datadog-agent/comp/core/log/def"
"github.com/DataDog/datadog-agent/pkg/util/hostname"
"go.uber.org/atomic"
)

type haAgentImpl struct {
log log.Component
haAgentConfigs *haAgentConfigs
isLeader *atomic.Bool
}

func newHaAgentImpl(log log.Component, haAgentConfigs *haAgentConfigs) *haAgentImpl {
return &haAgentImpl{
log: log,
haAgentConfigs: haAgentConfigs,
isLeader: atomic.NewBool(false),
}
}

func (h *haAgentImpl) Enabled() bool {
return h.haAgentConfigs.enabled
}

func (h *haAgentImpl) GetGroup() string {
return h.haAgentConfigs.group
}

func (h *haAgentImpl) IsLeader() bool {
return h.isLeader.Load()
}

func (h *haAgentImpl) SetLeader(leaderAgentHostname string) {
agentHostname, err := hostname.Get(context.TODO())
if err != nil {
h.log.Warnf("Error getting the hostname: %v", err)
return
}
h.isLeader.Store(agentHostname == leaderAgentHostname)
}
33 changes: 33 additions & 0 deletions comp/haagent/impl/haagent_comp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2024-present Datadog, Inc.

// Package haagentimpl implements the haagent component interface
package haagentimpl

import (
"github.com/DataDog/datadog-agent/comp/core/config"
log "github.com/DataDog/datadog-agent/comp/core/log/def"
haagent "github.com/DataDog/datadog-agent/comp/haagent/def"
)

// Requires defines the dependencies for the haagent component
type Requires struct {
Logger log.Component
AgentConfig config.Component
}

// Provides defines the output of the haagent component
type Provides struct {
Comp haagent.Component
}

// NewComponent creates a new haagent component
func NewComponent(reqs Requires) (Provides, error) {
haAgentConfigs := newHaAgentConfigs(reqs.AgentConfig)
provides := Provides{
Comp: newHaAgentImpl(reqs.Logger, haAgentConfigs),
}
return provides, nil
}
62 changes: 62 additions & 0 deletions comp/haagent/impl/haagent_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2024-present Datadog, Inc.

package haagentimpl

import (
"testing"

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

func Test_Enabled(t *testing.T) {
tests := []struct {
name string
configs map[string]interface{}
expectedEnabled bool
}{
{
name: "enabled",
configs: map[string]interface{}{
"ha_agent.enabled": true,
},
expectedEnabled: true,
},
{
name: "disabled",
configs: map[string]interface{}{
"ha_agent.enabled": false,
},
expectedEnabled: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
haAgent := newTestHaAgentComponent(t, tt.configs)
assert.Equal(t, tt.expectedEnabled, haAgent.Enabled())
})
}
}

func Test_GetGroup(t *testing.T) {
agentConfigs := map[string]interface{}{
"ha_agent.group": "my-group-01",
}
haAgent := newTestHaAgentComponent(t, agentConfigs)
assert.Equal(t, "my-group-01", haAgent.GetGroup())
}

func Test_IsLeader_SetLeader(t *testing.T) {
agentConfigs := map[string]interface{}{
"hostname": "my-agent-hostname",
}
haAgent := newTestHaAgentComponent(t, agentConfigs)

haAgent.SetLeader("another-agent")
assert.False(t, haAgent.IsLeader())

haAgent.SetLeader("my-agent-hostname")
assert.True(t, haAgent.IsLeader())
}
37 changes: 37 additions & 0 deletions comp/haagent/impl/haagent_testutils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2024-present Datadog, Inc.

package haagentimpl

import (
"testing"

"github.com/DataDog/datadog-agent/comp/core/config"
logmock "github.com/DataDog/datadog-agent/comp/core/log/mock"
haagent "github.com/DataDog/datadog-agent/comp/haagent/def"
"github.com/DataDog/datadog-agent/pkg/util/fxutil"
"github.com/stretchr/testify/require"
"go.uber.org/fx"
)

func newTestHaAgentComponent(t *testing.T, agentConfigs map[string]interface{}) haagent.Component {
logComponent := logmock.New(t)
agentConfigComponent := fxutil.Test[config.Component](t, fx.Options(
config.MockModule(),
fx.Replace(config.MockParams{Overrides: agentConfigs}),
))

requires := Requires{
Logger: logComponent,
AgentConfig: agentConfigComponent,
}

provides, err := NewComponent(requires)
require.NoError(t, err)

comp := provides.Comp
require.NotNil(t, comp)
return comp
}
45 changes: 45 additions & 0 deletions comp/haagent/mock/mock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2024-present Datadog, Inc.

//go:build test

// Package mock provides a mock for the haagent component
package mock

import (
"testing"

log "github.com/DataDog/datadog-agent/comp/core/log/def"
haagent "github.com/DataDog/datadog-agent/comp/haagent/def"
)

type mock struct {
Logger log.Component
}

func (m *mock) GetGroup() string {
return "mockGroup01"
}

func (m *mock) Enabled() bool {
return true
}

func (m *mock) SetLeader(_ string) {
}

func (m *mock) IsLeader() bool { return false }

// Provides that defines the output of mocked snmpscan component
type Provides struct {
comp haagent.Component
}

// Mock returns a mock for haagent component.
func Mock(_ *testing.T) Provides {
return Provides{
comp: &mock{},
}
}
4 changes: 4 additions & 0 deletions pkg/config/setup/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,10 @@ func InitConfig(config pkgconfigmodel.Setup) {
config.BindEnvAndSetDefault("network_path.collector.reverse_dns_enrichment.timeout", 5000)
bindEnvAndSetLogsConfigKeys(config, "network_path.forwarder.")

// HA Agent
config.BindEnvAndSetDefault("ha_agent.enabled", false)
config.BindEnv("ha_agent.group")

// Kube ApiServer
config.BindEnvAndSetDefault("kubernetes_kubeconfig_path", "")
config.BindEnvAndSetDefault("kubernetes_apiserver_ca_path", "")
Expand Down
11 changes: 11 additions & 0 deletions releasenotes/notes/add_haagent_comp-060918c70bcadb08.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Each section from every release note are combined when the
# CHANGELOG.rst is rendered. So the text needs to be worded so that
# it does not depend on any information only available in another
# section. This may mean repeating some details, but each section
# must be readable independently of the other.
#
# Each section note must be formatted as reStructuredText.
---
features:
- |
[ha-agent] Add haagent component used for HA Agent feature.

0 comments on commit a166214

Please sign in to comment.