Skip to content

Commit 798482a

Browse files
authored
Merge pull request #39 from netboxlabs/develop
release 🚚
2 parents a825e71 + b2f3d7f commit 798482a

38 files changed

+415
-722
lines changed

.github/golangci.yaml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
run:
2+
timeout: 5m
3+
modules-download-mode: readonly
4+
5+
output:
6+
formats: colored-line-number
7+
8+
linters:
9+
enable:
10+
- revive
11+
- errcheck
12+
- unused
13+
- staticcheck
14+
- ineffassign
15+
- govet
16+
- gosimple
17+
- bodyclose
18+
- gci
19+
- gofumpt
20+
21+
issues:
22+
exclude-use-default: false
23+
exclude-rules:
24+
- path: /*.go
25+
text: "package-comments: should have a package comment"
26+
linters:
27+
- revive
28+
29+
severity:
30+
default-severity: error
31+
32+
linters-settings:
33+
gci:
34+
sections:
35+
- standard
36+
- default
37+
- prefix(github.com/netboxlabs/orb-agent)
38+
custom-order: true
39+
go-fumpt:
40+
extra-rules: true

.github/workflows/lint.yaml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Orb Agent - lint
2+
on:
3+
push:
4+
branches:
5+
- "!release"
6+
pull_request:
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
golangci:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
- name: Setup Go
18+
uses: actions/setup-go@v4
19+
with:
20+
go-version: '1.23'
21+
check-latest: true
22+
- name: Lint
23+
uses: golangci/golangci-lint-action@v3
24+
with:
25+
version: v1.62
26+
working-directory: .
27+
args: --config .github/golangci.yaml
28+
skip-pkg-cache: true
29+
skip-build-cache: true

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ test-coverage:
4747
@cat .coverage/cover.out.tmp | grep -Ev "cmd" > .coverage/cover.out
4848
@go tool cover -func=.coverage/cover.out | grep total | awk '{print substr($$3, 1, length($$3)-1)}' > .coverage/coverage.txt
4949

50+
.PHONY: lint
51+
lint:
52+
@golangci-lint run ./... --config .github/golangci.yaml
53+
54+
.PHONY: fix-lint
55+
fix-lint:
56+
@golangci-lint run ./... --config .github/golangci.yaml --fix
57+
5058
agent:
5159
docker build --no-cache \
5260
--build-arg GOARCH=$(GOARCH) \

README.md

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,20 @@
22
Orb agent is a component of the NetBox Discovery solution. It provides network discovery and observability capabilities and is developed by NetBox Labs.
33

44
## Project status
5-
65
The Orb agent project is currently in the Public Preview stage. For details, please see [NetBox Labs Product and Feature Lifecycle](https://docs.netboxlabs.com/product_feature_lifecycle/). We actively welcome feedback to help us identify and prioritize bugs, features, and improvements.
76

87
## Getting Started
9-
To run `orb-agent`, first pull the Docker image from [Docker Hub](https://hub.docker.com/r/netboxlabs/orb-agent):
10-
8+
To get started with `orb-agent`, first pull the Docker image from [Docker Hub](https://hub.docker.com/r/netboxlabs/orb-agent):
119

1210
```sh
1311
docker pull netboxlabs/orb-agent:latest
1412
```
1513

1614
## Orb Agent Configuration
17-
To run, the Orb agent requires a configuration file. This configuration file consists of three main sections: `Config Manager`, `Backends`, and `Policies`.
18-
15+
The Orb agent requires a configuration file. This file consists of three main sections: `config_manager`, `backends`, and `policies`.
1916

2017
### Config Manager
21-
The `Config Manager` section specifies how Orb agent should retrieve it's configuration information. The configuration manager is responsible for processing the configuration to retrieve policies and pass them to the appropriate backend.
18+
The `config_manager` section specifies how Orb agent should retrieve it's configuration information. The configuration manager is responsible for processing the configuration to retrieve policies and pass them to the appropriate backend.
2219

2320
```yaml
2421
orb:
@@ -30,7 +27,7 @@ orb:
3027
Currently, only the `local` manager is supported, which retrieves policies from the local configuration file passed to the agent.
3128

3229
### Backends
33-
The `Backends` section specifies what Orb agent backends should be enabled. Each Orb agent backend offers specific discovery or observability capabilities and may require specific configuration information.
30+
The `backends` section specifies what Orb agent backends should be enabled. Each Orb agent backend offers specific discovery or observability capabilities and may require specific configuration information.
3431

3532
```yaml
3633
orb:
@@ -42,38 +39,45 @@ orb:
4239
Only the `network_discovery` and `device_discovery` backends are currently supported. They do not require any special configuration.
4340
- [Device Discovery](./docs/backends/device_discovery.md)
4441
- [Network Discovery](./docs/backends/network_discovery.md)
45-
### Commons
46-
A special `common` subsection under `Backends` defines configuration settings that are shared with all backends. Currently, it supports passing [diode](https://github.com/netboxlabs/diode) server settings to all backends.
42+
43+
#### Common
44+
A special `common` subsection under `backends` defines configuration settings that are shared with all backends. Currently, it supports passing [diode](https://github.com/netboxlabs/diode) server settings to all backends.
4745

4846
```yaml
4947
backends:
5048
...
5149
common:
52-
diode:
53-
target: grpc://192.168.0.22:8080/diode
54-
api_key: ${DIODE_API_KEY}
55-
agent_name: agent01
50+
diode:
51+
target: grpc://192.168.0.22:8080/diode
52+
api_key: ${DIODE_API_KEY}
53+
agent_name: agent01
5654
```
5755
58-
5956
### Policies
60-
The `Policies` section specifies what discovery policies should be passed to each backend. Policies define specific settings for discovery (such as scheduling and default properties) and the scope (targets). Backends can run multiple policies simultaneously, but for each backend all policies must have a unique name. These policies are defined in the `policies` section and are grouped under a subsection for each backend:
57+
The `policies` section specifies what discovery policies should be passed to each backend. Policies define specific settings for discovery (such as scheduling and default properties) and the scope (targets). Backends can run multiple policies simultaneously, but for each backend all policies must have a unique name. These policies are defined in the `policies` section and are grouped under a subsection for each backend:
6158

6259
```yaml
6360
orb:
6461
...
6562
policies:
6663
device_discovery:
6764
device_policy_1:
68-
# see device_discovery section
65+
# see docs/backends/device_discovery.md
6966
network_discovery:
7067
network_policy_1:
71-
# see network_discovery section
68+
# see docs/backends/network_discovery.md
7269
```
7370

74-
## Configuration samples
75-
You can find sample configurations [here](./docs/config_samples.md) of how to configure Orb agent to run network and device discoveries.
71+
## Running the agent
7672

77-
## Required Notice
73+
To run `orb-agent`, use the following command from the directory where your created your `agent.yaml` file:
7874

79-
Copyright NetBox Labs, Inc.
75+
```sh
76+
docker run -v $(PWD):/opt/orb/ netboxlabs/orb-agent:latest run -c /opt/orb/agent.yaml
77+
```
78+
79+
### Configuration samples
80+
You can find complete sample configurations [here](./docs/config_samples.md) of how to configure Orb agent to run network and device discoveries, as well as the relevant `docker run` commands.
81+
82+
## Required Notice
83+
Copyright NetBox Labs, Inc.

agent/agent.go

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99

1010
mqtt "github.com/eclipse/paho.mqtt.golang"
1111
"github.com/google/uuid"
12-
_ "github.com/mattn/go-sqlite3"
1312
"github.com/mitchellh/mapstructure"
1413
"github.com/orb-community/orb/fleet"
1514
"go.uber.org/zap"
@@ -20,10 +19,9 @@ import (
2019
"github.com/netboxlabs/orb-agent/agent/version"
2120
)
2221

23-
var (
24-
ErrMqttConnection = errors.New("failed to connect to a broker")
25-
)
22+
const routineKey config.ContextKey = "routine"
2623

24+
// Agent is the interface that all agents must implement
2725
type Agent interface {
2826
Start(ctx context.Context, cancelFunc context.CancelFunc) error
2927
Stop(ctx context.Context)
@@ -35,7 +33,7 @@ type orbAgent struct {
3533
logger *zap.Logger
3634
config config.Config
3735
client mqtt.Client
38-
agent_id string
36+
agentID string
3937
backends map[string]backend.Backend
4038
backendState map[string]*backend.State
4139
backendsCommon config.BackendCommons
@@ -49,38 +47,29 @@ type orbAgent struct {
4947
heartbeatCancel context.CancelFunc
5048

5149
// Agent RPC channel, configured from command line
52-
baseTopic string
53-
rpcToCoreTopic string
54-
rpcFromCoreTopic string
55-
capabilitiesTopic string
56-
heartbeatsTopic string
57-
logTopic string
50+
baseTopic string
51+
rpcFromCoreTopic string
52+
heartbeatsTopic string
5853

5954
// Retry Mechanism to ensure the Request is received
60-
groupRequestTicker *time.Ticker
6155
groupRequestSucceeded context.CancelFunc
62-
policyRequestTicker *time.Ticker
6356
policyRequestSucceeded context.CancelFunc
6457

6558
// AgentGroup channels sent from core
66-
groupsInfos map[string]GroupInfo
59+
groupsInfos map[string]groupInfo
6760

6861
policyManager manager.PolicyManager
69-
configManager config.ConfigManager
62+
configManager config.Manager
7063
}
7164

72-
const retryRequestDuration = time.Second
73-
const retryRequestFixedTime = 15
74-
const retryDurationIncrPerAttempts = 10
75-
const retryMaxAttempts = 4
76-
77-
type GroupInfo struct {
65+
type groupInfo struct {
7866
Name string
7967
ChannelID string
8068
}
8169

8270
var _ Agent = (*orbAgent)(nil)
8371

72+
// New creates a new agent
8473
func New(logger *zap.Logger, c config.Config) (Agent, error) {
8574
pm, err := manager.New(logger, c)
8675
if err != nil {
@@ -93,11 +82,10 @@ func New(logger *zap.Logger, c config.Config) (Agent, error) {
9382
}
9483
cm := config.New(logger, c.OrbAgent.ConfigManager)
9584

96-
return &orbAgent{logger: logger, config: c, policyManager: pm, configManager: cm, groupsInfos: make(map[string]GroupInfo)}, nil
85+
return &orbAgent{logger: logger, config: c, policyManager: pm, configManager: cm, groupsInfos: make(map[string]groupInfo)}, nil
9786
}
9887

9988
func (a *orbAgent) managePolicies() error {
100-
10189
if a.config.OrbAgent.Policies == nil {
10290
return errors.New("no policies specified")
10391
}
@@ -147,7 +135,7 @@ func (a *orbAgent) startBackends(agentCtx context.Context) error {
147135
a.logger.Info("failed to configure backend", zap.String("backend", name), zap.Error(err))
148136
return err
149137
}
150-
backendCtx := context.WithValue(agentCtx, "routine", name)
138+
backendCtx := context.WithValue(agentCtx, routineKey, name)
151139
backendCtx = a.configManager.GetContext(backendCtx)
152140
a.backends[name] = be
153141
initialState := be.GetInitialState()
@@ -177,12 +165,12 @@ func (a *orbAgent) Start(ctx context.Context, cancelFunc context.CancelFunc) err
177165
defer func(t time.Time) {
178166
a.logger.Debug("Startup of agent execution duration", zap.String("Start() execution duration", time.Since(t).String()))
179167
}(startTime)
180-
agentCtx := context.WithValue(ctx, "routine", "agentRoutine")
181-
asyncCtx, cancelAllAsync := context.WithCancel(context.WithValue(ctx, "routine", "asyncParent"))
168+
agentCtx := context.WithValue(ctx, routineKey, "agentRoutine")
169+
asyncCtx, cancelAllAsync := context.WithCancel(context.WithValue(ctx, routineKey, "asyncParent"))
182170
a.asyncContext = asyncCtx
183171
a.rpcFromCancelFunc = cancelAllAsync
184172
a.cancelFunction = cancelFunc
185-
a.logger.Info("agent started", zap.String("version", version.GetBuildVersion()), zap.Any("routine", agentCtx.Value("routine")))
173+
a.logger.Info("agent started", zap.String("version", version.GetBuildVersion()), zap.Any("routine", agentCtx.Value(routineKey)))
186174
mqtt.CRITICAL = &agentLoggerCritical{a: a}
187175
mqtt.ERROR = &agentLoggerError{a: a}
188176

@@ -212,7 +200,7 @@ func (a *orbAgent) logonWithHeartbeat() {
212200
}
213201

214202
func (a *orbAgent) logoffWithHeartbeat(ctx context.Context) {
215-
a.logger.Debug("stopping heartbeat, going offline status", zap.Any("routine", ctx.Value("routine")))
203+
a.logger.Debug("stopping heartbeat, going offline status", zap.Any("routine", ctx.Value(routineKey)))
216204
if a.heartbeatCtx != nil {
217205
a.heartbeatCancel()
218206
}
@@ -222,8 +210,9 @@ func (a *orbAgent) logoffWithHeartbeat(ctx context.Context) {
222210
}
223211
}
224212
}
213+
225214
func (a *orbAgent) Stop(ctx context.Context) {
226-
a.logger.Info("routine call for stop agent", zap.Any("routine", ctx.Value("routine")))
215+
a.logger.Info("routine call for stop agent", zap.Any("routine", ctx.Value(routineKey)))
227216
if a.rpcFromCancelFunc != nil {
228217
a.rpcFromCancelFunc()
229218
}
@@ -256,7 +245,7 @@ func (a *orbAgent) RestartBackend(ctx context.Context, name string, reason strin
256245

257246
be := a.backends[name]
258247
a.logger.Info("restarting backend", zap.String("backend", name), zap.String("reason", reason))
259-
a.backendState[name].RestartCount += 1
248+
a.backendState[name].RestartCount++
260249
a.backendState[name].LastRestartTS = time.Now()
261250
a.backendState[name].LastRestartReason = reason
262251
a.logger.Info("removing policies", zap.String("backend", name))
@@ -272,7 +261,7 @@ func (a *orbAgent) RestartBackend(ctx context.Context, name string, reason strin
272261
a.backendState[name].LastError = fmt.Sprintf("failed to reset backend: %v", err)
273262
a.logger.Error("failed to reset backend", zap.String("backend", name), zap.Error(err))
274263
}
275-
be.SetCommsClient(a.agent_id, &a.client, fmt.Sprintf("%s/?/%s", a.baseTopic, name))
264+
be.SetCommsClient(a.agentID, &a.client, fmt.Sprintf("%s/?/%s", a.baseTopic, name))
276265

277266
return nil
278267
}
@@ -294,7 +283,7 @@ func (a *orbAgent) RestartAll(ctx context.Context, reason string) error {
294283
}
295284

296285
func (a *orbAgent) extendContext(routine string) (context.Context, context.CancelFunc) {
297-
uuidTraceId := uuid.NewString()
298-
a.logger.Debug("creating context for receiving message", zap.String("routine", routine), zap.String("trace-id", uuidTraceId))
299-
return context.WithCancel(context.WithValue(context.WithValue(a.asyncContext, "routine", routine), "trace-id", uuidTraceId))
286+
uuidTraceID := uuid.NewString()
287+
a.logger.Debug("creating context for receiving message", zap.String("routine", routine), zap.String("trace-id", uuidTraceID))
288+
return context.WithCancel(context.WithValue(context.WithValue(a.asyncContext, routineKey, routine), config.ContextKey("trace-id"), uuidTraceID))
300289
}

agent/agent_prof_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
)
77

88
func Test_orbAgent_startBackends(t *testing.T) {
9-
109
type args struct {
1110
agentCtx context.Context
1211
}

0 commit comments

Comments
 (0)