@@ -4,17 +4,18 @@ import (
4
4
"context"
5
5
"errors"
6
6
"fmt"
7
+ "log/slog"
7
8
"runtime"
8
9
"time"
9
10
10
11
"github.com/google/uuid"
11
- "github.com/mitchellh/mapstructure"
12
- "go.uber.org/zap"
12
+ "gopkg.in/yaml.v3"
13
13
14
14
"github.com/netboxlabs/orb-agent/agent/backend"
15
15
"github.com/netboxlabs/orb-agent/agent/config"
16
16
"github.com/netboxlabs/orb-agent/agent/configmgr"
17
17
"github.com/netboxlabs/orb-agent/agent/policymgr"
18
+ "github.com/netboxlabs/orb-agent/agent/secretsmgr"
18
19
"github.com/netboxlabs/orb-agent/agent/version"
19
20
)
20
21
@@ -29,7 +30,7 @@ type Agent interface {
29
30
}
30
31
31
32
type orbAgent struct {
32
- logger * zap .Logger
33
+ logger * slog .Logger
33
34
config config.Config
34
35
backends map [string ]backend.Backend
35
36
backendState map [string ]* backend.State
@@ -49,8 +50,9 @@ type orbAgent struct {
49
50
// AgentGroup channels sent from core
50
51
groupsInfos map [string ]groupInfo
51
52
52
- policyManager policymgr.PolicyManager
53
- configManager configmgr.Manager
53
+ policyManager policymgr.PolicyManager
54
+ configManager configmgr.Manager
55
+ secretsManager secretsmgr.Manager
54
56
}
55
57
56
58
type groupInfo struct {
@@ -61,49 +63,68 @@ type groupInfo struct {
61
63
var _ Agent = (* orbAgent )(nil )
62
64
63
65
// New creates a new agent
64
- func New (logger * zap.Logger , c config.Config ) (Agent , error ) {
65
- pm , err := policymgr .New (logger , c )
66
+ func New (logger * slog.Logger , c config.Config ) (Agent , error ) {
67
+ sm := secretsmgr .New (logger , c .OrbAgent .SecretsManger )
68
+ pm , err := policymgr .New (logger , sm , c )
66
69
if err != nil {
67
- logger .Error ("error during create policy manager, exiting" , zap . Error ( err ))
70
+ logger .Error ("error during create policy manager, exiting" , slog . Any ( "error" , err ))
68
71
return nil , err
69
72
}
70
73
if pm .GetRepo () == nil {
71
- logger .Error ("policy manager failed to get repository" , zap . Error ( err ))
74
+ logger .Error ("policy manager failed to get repository" , slog . Any ( "error" , err ))
72
75
return nil , err
73
76
}
74
- cm := configmgr .New (logger , pm , c .OrbAgent .ConfigManager )
75
77
76
- return & orbAgent {logger : logger , config : c , policyManager : pm , configManager : cm , groupsInfos : make (map [string ]groupInfo )}, nil
78
+ cm := configmgr .New (logger , pm , c .OrbAgent .ConfigManager .Active )
79
+
80
+ return & orbAgent {
81
+ logger : logger , config : c , policyManager : pm , configManager : cm ,
82
+ secretsManager : sm , groupsInfos : make (map [string ]groupInfo ),
83
+ }, nil
77
84
}
78
85
79
- func (a * orbAgent ) startBackends (agentCtx context.Context ) error {
80
- a .logger .Info ("registered backends" , zap .Strings ("values" , backend .GetList ()))
81
- a .logger .Info ("requested backends" , zap .Any ("values" , a .config .OrbAgent .Backends ))
82
- if len (a .config .OrbAgent .Backends ) == 0 {
86
+ func (a * orbAgent ) startBackends (agentCtx context.Context , cfgBackends map [string ]any , labels map [string ]string ) error {
87
+ a .logger .Info ("registered backends" , slog .Any ("values" , backend .GetList ()))
88
+ if len (cfgBackends ) == 0 {
83
89
return errors .New ("no backends specified" )
84
90
}
85
- a .backends = make (map [string ]backend.Backend , len (a . config . OrbAgent . Backends ))
91
+ a .backends = make (map [string ]backend.Backend , len (cfgBackends ))
86
92
a .backendState = make (map [string ]* backend.State )
87
93
88
94
var commonConfig config.BackendCommons
89
- if v , prs := a .config .OrbAgent .Backends ["common" ]; prs {
90
- if err := mapstructure .Decode (v , & commonConfig ); err != nil {
91
- return fmt .Errorf ("failed to decode common backend config: %w" , err )
95
+ if v , prs := cfgBackends ["common" ]; prs {
96
+ bytes , err := yaml .Marshal (v )
97
+ if err != nil {
98
+ return err
92
99
}
100
+ err = yaml .Unmarshal (bytes , & commonConfig )
101
+ if err != nil {
102
+ a .logger .Info ("failed to marshal common backend config" , slog .Any ("error" , err ))
103
+ return err
104
+ }
105
+ } else {
106
+ commonConfig = config.BackendCommons {}
93
107
}
94
- commonConfig .Otel .AgentLabels = a . config . OrbAgent . Labels
108
+ commonConfig .Otel .AgentLabels = labels
95
109
a .backendsCommon = commonConfig
96
- delete (a .config .OrbAgent .Backends , "common" )
97
-
98
- for name , configurationEntry := range a .config .OrbAgent .Backends {
99
-
110
+ delete (cfgBackends , "common" )
111
+
112
+ for name , configurationEntry := range cfgBackends {
113
+ var cEntity map [string ]any
114
+ if configurationEntry != nil {
115
+ var ok bool
116
+ cEntity , ok = configurationEntry .(map [string ]any )
117
+ if ! ok {
118
+ return errors .New ("invalid backend configuration format for backend: " + name )
119
+ }
120
+ }
100
121
if ! backend .HaveBackend (name ) {
101
122
return errors .New ("specified backend does not exist: " + name )
102
123
}
103
124
be := backend .GetBackend (name )
104
125
105
- if err := be .Configure (a .logger , a .policyManager .GetRepo (), configurationEntry , a .backendsCommon ); err != nil {
106
- a .logger .Info ("failed to configure backend" , zap .String ("backend" , name ), zap . Error ( err ))
126
+ if err := be .Configure (a .logger , a .policyManager .GetRepo (), cEntity , a .backendsCommon ); err != nil {
127
+ a .logger .Info ("failed to configure backend" , slog .String ("backend" , name ), slog . Any ( "error" , err ))
107
128
return err
108
129
}
109
130
backendCtx := context .WithValue (agentCtx , routineKey , name )
@@ -115,7 +136,7 @@ func (a *orbAgent) startBackends(agentCtx context.Context) error {
115
136
LastRestartTS : time .Now (),
116
137
}
117
138
if err := be .Start (context .WithCancel (backendCtx )); err != nil {
118
- a .logger .Info ("failed to start backend" , zap .String ("backend" , name ), zap . Error ( err ))
139
+ a .logger .Info ("failed to start backend" , slog .String ("backend" , name ), slog . Any ( "error" , err ))
119
140
var errMessage string
120
141
if initialState == backend .BackendError {
121
142
errMessage = err .Error ()
@@ -134,20 +155,33 @@ func (a *orbAgent) startBackends(agentCtx context.Context) error {
134
155
func (a * orbAgent ) Start (ctx context.Context , cancelFunc context.CancelFunc ) error {
135
156
startTime := time .Now ()
136
157
defer func (t time.Time ) {
137
- a .logger .Debug ("Startup of agent execution duration" , zap .String ("Start() execution duration" , time .Since (t ).String ()))
158
+ a .logger .Debug ("Startup of agent execution duration" , slog .String ("Start() execution duration" , time .Since (t ).String ()))
138
159
}(startTime )
139
160
agentCtx := context .WithValue (ctx , routineKey , "agentRoutine" )
140
161
asyncCtx , cancelAllAsync := context .WithCancel (context .WithValue (ctx , routineKey , "asyncParent" ))
141
162
a .asyncContext = asyncCtx
142
163
a .rpcFromCancelFunc = cancelAllAsync
143
164
a .cancelFunction = cancelFunc
144
- a .logger .Info ("agent started" , zap .String ("version" , version .GetBuildVersion ()), zap .Any ("routine" , agentCtx .Value (routineKey )))
165
+ a .logger .Info ("agent started" , slog .String ("version" , version .GetBuildVersion ()), slog .Any ("routine" , agentCtx .Value (routineKey )))
166
+ a .logger .Info ("requested backends" , slog .Any ("values" , a .config .OrbAgent .Backends ))
145
167
146
- if err := a .startBackends (ctx ); err != nil {
168
+ if err := a .secretsManager .Start (ctx ); err != nil {
169
+ a .logger .Error ("error during start secrets manager" , slog .Any ("error" , err ))
147
170
return err
148
171
}
149
172
150
- if err := a .configManager .Start (a .config , a .backends ); err != nil {
173
+ var err error
174
+ if a .config .OrbAgent .Backends ,
175
+ a .config .OrbAgent .ConfigManager ,
176
+ err = a .secretsManager .SolveConfigSecrets (a .config .OrbAgent .Backends , a .config .OrbAgent .ConfigManager ); err != nil {
177
+ return err
178
+ }
179
+
180
+ if err = a .startBackends (ctx , a .config .OrbAgent .Backends , a .config .OrbAgent .Labels ); err != nil {
181
+ return err
182
+ }
183
+
184
+ if err = a .configManager .Start (a .config , a .backends ); err != nil {
151
185
return err
152
186
}
153
187
@@ -162,27 +196,27 @@ func (a *orbAgent) logonWithHeartbeat() {
162
196
}
163
197
164
198
func (a * orbAgent ) logoffWithHeartbeat (ctx context.Context ) {
165
- a .logger .Debug ("stopping heartbeat, going offline status" , zap .Any ("routine" , ctx .Value (routineKey )))
199
+ a .logger .Debug ("stopping heartbeat, going offline status" , slog .Any ("routine" , ctx .Value (routineKey )))
166
200
if a .heartbeatCtx != nil {
167
201
a .heartbeatCancel ()
168
202
}
169
203
}
170
204
171
205
func (a * orbAgent ) Stop (ctx context.Context ) {
172
- a .logger .Info ("routine call for stop agent" , zap .Any ("routine" , ctx .Value (routineKey )))
206
+ a .logger .Info ("routine call for stop agent" , slog .Any ("routine" , ctx .Value (routineKey )))
173
207
if a .rpcFromCancelFunc != nil {
174
208
a .rpcFromCancelFunc ()
175
209
}
176
210
for name , b := range a .backends {
177
211
if state , _ , _ := b .GetRunningStatus (); state == backend .Running {
178
- a .logger .Debug ("stopping backend" , zap .String ("backend" , name ))
212
+ a .logger .Debug ("stopping backend" , slog .String ("backend" , name ))
179
213
if err := b .Stop (ctx ); err != nil {
180
- a .logger .Error ("error while stopping the backend" , zap .String ("backend" , name ))
214
+ a .logger .Error ("error while stopping the backend" , slog .String ("backend" , name ))
181
215
}
182
216
}
183
217
}
184
218
a .logoffWithHeartbeat (ctx )
185
- a .logger .Debug ("stopping agent with number of go routines and go calls" , zap .Int ("goroutines" , runtime .NumGoroutine ()), zap .Int64 ("gocalls" , runtime .NumCgoCall ()))
219
+ a .logger .Debug ("stopping agent with number of go routines and go calls" , slog .Int ("goroutines" , runtime .NumGoroutine ()), slog .Int64 ("gocalls" , runtime .NumCgoCall ()))
186
220
if a .policyRequestSucceeded != nil {
187
221
a .policyRequestSucceeded ()
188
222
}
@@ -198,22 +232,30 @@ func (a *orbAgent) RestartBackend(ctx context.Context, name string, reason strin
198
232
}
199
233
200
234
be := a .backends [name ]
201
- a .logger .Info ("restarting backend" , zap .String ("backend" , name ), zap .String ("reason" , reason ))
235
+ a .logger .Info ("restarting backend" , slog .String ("backend" , name ), slog .String ("reason" , reason ))
202
236
a .backendState [name ].RestartCount ++
203
237
a .backendState [name ].LastRestartTS = time .Now ()
204
238
a .backendState [name ].LastRestartReason = reason
205
- a .logger .Info ("removing policies" , zap .String ("backend" , name ))
239
+ a .logger .Info ("removing policies" , slog .String ("backend" , name ))
206
240
if err := a .policyManager .RemoveBackendPolicies (be , true ); err != nil {
207
- a .logger .Error ("failed to remove policies" , zap .String ("backend" , name ), zap .Error (err ))
241
+ a .logger .Error ("failed to remove policies" , slog .String ("backend" , name ), slog .Any ("error" , err ))
242
+ }
243
+ var beConfig map [string ]any
244
+ if a .config .OrbAgent .Backends [name ] != nil {
245
+ var ok bool
246
+ beConfig , ok = a .config .OrbAgent .Backends [name ].(map [string ]any )
247
+ if ! ok {
248
+ return errors .New ("backend not found: " + name )
249
+ }
208
250
}
209
- if err := be .Configure (a .logger , a .policyManager .GetRepo (), a . config . OrbAgent . Backends [ name ] , a .backendsCommon ); err != nil {
251
+ if err := be .Configure (a .logger , a .policyManager .GetRepo (), beConfig , a .backendsCommon ); err != nil {
210
252
return err
211
253
}
212
- a .logger .Info ("resetting backend" , zap .String ("backend" , name ))
254
+ a .logger .Info ("resetting backend" , slog .String ("backend" , name ))
213
255
214
256
if err := be .FullReset (ctx ); err != nil {
215
257
a .backendState [name ].LastError = fmt .Sprintf ("failed to reset backend: %v" , err )
216
- a .logger .Error ("failed to reset backend" , zap .String ("backend" , name ), zap . Error ( err ))
258
+ a .logger .Error ("failed to reset backend" , slog .String ("backend" , name ), slog . Any ( "error" , err ))
217
259
}
218
260
219
261
return nil
@@ -222,12 +264,12 @@ func (a *orbAgent) RestartBackend(ctx context.Context, name string, reason strin
222
264
func (a * orbAgent ) RestartAll (ctx context.Context , reason string ) error {
223
265
ctx = a .configManager .GetContext (ctx )
224
266
a .logoffWithHeartbeat (ctx )
225
- a .logger .Info ("restarting comms" , zap .String ("reason" , reason ))
267
+ a .logger .Info ("restarting comms" , slog .String ("reason" , reason ))
226
268
for name := range a .backends {
227
- a .logger .Info ("restarting backend" , zap .String ("backend" , name ), zap .String ("reason" , reason ))
269
+ a .logger .Info ("restarting backend" , slog .String ("backend" , name ), slog .String ("reason" , reason ))
228
270
err := a .RestartBackend (ctx , name , reason )
229
271
if err != nil {
230
- a .logger .Error ("failed to restart backend" , zap . Error ( err ))
272
+ a .logger .Error ("failed to restart backend" , slog . Any ( "error" , err ))
231
273
}
232
274
}
233
275
a .logger .Info ("all backends and comms were restarted" )
@@ -237,6 +279,6 @@ func (a *orbAgent) RestartAll(ctx context.Context, reason string) error {
237
279
238
280
func (a * orbAgent ) extendContext (routine string ) (context.Context , context.CancelFunc ) {
239
281
uuidTraceID := uuid .NewString ()
240
- a .logger .Debug ("creating context for receiving message" , zap .String ("routine" , routine ), zap .String ("trace-id" , uuidTraceID ))
282
+ a .logger .Debug ("creating context for receiving message" , slog .String ("routine" , routine ), slog .String ("trace-id" , uuidTraceID ))
241
283
return context .WithCancel (context .WithValue (context .WithValue (a .asyncContext , routineKey , routine ), config .ContextKey ("trace-id" ), uuidTraceID ))
242
284
}
0 commit comments