@@ -10,6 +10,8 @@ import (
10
10
"log/slog"
11
11
"sync"
12
12
13
+ "github.com/nginx/agent/v3/internal/model"
14
+
13
15
"google.golang.org/protobuf/types/known/timestamppb"
14
16
15
17
mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1"
@@ -38,75 +40,102 @@ type (
38
40
}
39
41
40
42
CommandPlugin struct {
41
- messagePipe bus.MessagePipeInterface
42
- config * config.Config
43
- subscribeCancel context.CancelFunc
44
- conn grpc.GrpcConnectionInterface
45
- commandService commandService
46
- subscribeChannel chan * mpi.ManagementPlaneRequest
47
- subscribeMutex sync.Mutex
43
+ messagePipe bus.MessagePipeInterface
44
+ config * config.Config
45
+ subscribeCancel context.CancelFunc
46
+ conn grpc.GrpcConnectionInterface
47
+ commandService commandService
48
+ subscribeChannel chan * mpi.ManagementPlaneRequest
49
+ commandServerType model.ServerType
50
+ subscribeMutex sync.Mutex
48
51
}
49
52
)
50
53
51
- func NewCommandPlugin (agentConfig * config.Config , grpcConnection grpc.GrpcConnectionInterface ) * CommandPlugin {
54
+ func NewCommandPlugin (agentConfig * config.Config , grpcConnection grpc.GrpcConnectionInterface ,
55
+ commandServerType model.ServerType ,
56
+ ) * CommandPlugin {
52
57
return & CommandPlugin {
53
- config : agentConfig ,
54
- conn : grpcConnection ,
55
- subscribeChannel : make (chan * mpi.ManagementPlaneRequest ),
58
+ config : agentConfig ,
59
+ conn : grpcConnection ,
60
+ subscribeChannel : make (chan * mpi.ManagementPlaneRequest ),
61
+ commandServerType : commandServerType ,
56
62
}
57
63
}
58
64
59
65
func (cp * CommandPlugin ) Init (ctx context.Context , messagePipe bus.MessagePipeInterface ) error {
60
- slog .DebugContext (ctx , "Starting command plugin" )
66
+ newCtx := context .WithValue (
67
+ ctx ,
68
+ logger .ServerTypeContextKey , slog .Any (logger .ServerTypeKey , cp .commandServerType .String ()),
69
+ )
70
+ slog .DebugContext (newCtx , "Starting command plugin" )
61
71
62
72
cp .messagePipe = messagePipe
63
73
cp .commandService = NewCommandService (cp .conn .CommandServiceClient (), cp .config , cp .subscribeChannel )
64
74
65
- go cp .monitorSubscribeChannel (ctx )
75
+ go cp .monitorSubscribeChannel (newCtx )
66
76
67
77
return nil
68
78
}
69
79
70
80
func (cp * CommandPlugin ) Close (ctx context.Context ) error {
71
- slog .InfoContext (ctx , "Closing command plugin" )
81
+ newCtx := context .WithValue (
82
+ ctx ,
83
+ logger .ServerTypeContextKey , slog .Any (logger .ServerTypeKey , cp .commandServerType .String ()),
84
+ )
85
+ slog .InfoContext (newCtx , "Closing command plugin" )
72
86
73
87
cp .subscribeMutex .Lock ()
74
88
if cp .subscribeCancel != nil {
75
89
cp .subscribeCancel ()
76
90
}
77
91
cp .subscribeMutex .Unlock ()
78
92
79
- return cp .conn .Close (ctx )
93
+ return cp .conn .Close (newCtx )
80
94
}
81
95
82
96
func (cp * CommandPlugin ) Info () * bus.Info {
83
97
return & bus.Info {
84
- Name : "command" ,
98
+ Name : cp . commandServerType . String () ,
85
99
}
86
100
}
87
101
88
102
func (cp * CommandPlugin ) Process (ctx context.Context , msg * bus.Message ) {
89
- switch msg .Topic {
90
- case bus .ConnectionResetTopic :
91
- cp .processConnectionReset (ctx , msg )
92
- case bus .ResourceUpdateTopic :
93
- cp .processResourceUpdate (ctx , msg )
94
- case bus .InstanceHealthTopic :
95
- cp .processInstanceHealth (ctx , msg )
96
- case bus .DataPlaneHealthResponseTopic :
97
- cp .processDataPlaneHealth (ctx , msg )
98
- case bus .DataPlaneResponseTopic :
99
- cp .processDataPlaneResponse (ctx , msg )
100
- default :
101
- slog .DebugContext (ctx , "Command plugin received unknown topic" , "topic" , msg .Topic )
103
+ slog .DebugContext (ctx , "Processing command" )
104
+
105
+ if logger .ServerType (ctx ) == "" {
106
+ ctx = context .WithValue (
107
+ ctx ,
108
+ logger .ServerTypeContextKey , slog .Any (logger .ServerTypeKey , cp .commandServerType .String ()),
109
+ )
110
+ }
111
+
112
+ if logger .ServerType (ctx ) == cp .commandServerType .String () {
113
+ switch msg .Topic {
114
+ case bus .ConnectionResetTopic :
115
+ cp .processConnectionReset (ctx , msg )
116
+ case bus .ResourceUpdateTopic :
117
+ cp .processResourceUpdate (ctx , msg )
118
+ case bus .InstanceHealthTopic :
119
+ cp .processInstanceHealth (ctx , msg )
120
+ case bus .DataPlaneHealthResponseTopic :
121
+ cp .processDataPlaneHealth (ctx , msg )
122
+ case bus .DataPlaneResponseTopic :
123
+ cp .processDataPlaneResponse (ctx , msg )
124
+ default :
125
+ slog .DebugContext (ctx , "Command plugin received unknown topic" , "topic" , msg .Topic )
126
+ }
102
127
}
103
128
}
104
129
105
130
func (cp * CommandPlugin ) processResourceUpdate (ctx context.Context , msg * bus.Message ) {
106
131
slog .DebugContext (ctx , "Command plugin received resource update message" )
107
132
if resource , ok := msg .Data .(* mpi.Resource ); ok {
108
133
if ! cp .commandService .IsConnected () {
109
- cp .createConnection (ctx , resource )
134
+ newCtx := context .WithValue (
135
+ ctx ,
136
+ logger .ServerTypeContextKey , slog .Any (logger .ServerTypeKey , cp .commandServerType .String ()),
137
+ )
138
+ cp .createConnection (newCtx , resource )
110
139
} else {
111
140
statusErr := cp .commandService .UpdateDataPlaneStatus (ctx , resource )
112
141
if statusErr != nil {
@@ -145,13 +174,14 @@ func (cp *CommandPlugin) processDataPlaneHealth(ctx context.Context, msg *bus.Me
145
174
correlationID := logger .CorrelationID (ctx )
146
175
if err != nil {
147
176
slog .ErrorContext (ctx , "Unable to update data plane health" , "error" , err )
148
- cp .messagePipe .Process (ctx , & bus.Message {
177
+
178
+ cp .processDataPlaneResponse (ctx , & bus.Message {
149
179
Topic : bus .DataPlaneResponseTopic ,
150
180
Data : cp .createDataPlaneResponse (correlationID , mpi .CommandResponse_COMMAND_STATUS_FAILURE ,
151
181
"Failed to send the health status update" , err .Error ()),
152
182
})
153
183
}
154
- cp .messagePipe . Process (ctx , & bus.Message {
184
+ cp .processDataPlaneResponse (ctx , & bus.Message {
155
185
Topic : bus .DataPlaneResponseTopic ,
156
186
Data : cp .createDataPlaneResponse (correlationID , mpi .CommandResponse_COMMAND_STATUS_OK ,
157
187
"Successfully sent health status update" , "" ),
@@ -208,6 +238,7 @@ func (cp *CommandPlugin) Subscriptions() []string {
208
238
}
209
239
}
210
240
241
+ // nolint: revive, cyclop
211
242
func (cp * CommandPlugin ) monitorSubscribeChannel (ctx context.Context ) {
212
243
for {
213
244
select {
@@ -226,12 +257,28 @@ func (cp *CommandPlugin) monitorSubscribeChannel(ctx context.Context) {
226
257
slog .InfoContext (ctx , "Received management plane config upload request" )
227
258
cp .handleConfigUploadRequest (newCtx , message )
228
259
case * mpi.ManagementPlaneRequest_ConfigApplyRequest :
260
+ if cp .commandServerType != model .Command {
261
+ slog .WarnContext (newCtx , "Auxiliary command server can not perform config apply" ,
262
+ "command_server_type" , cp .commandServerType .String ())
263
+ cp .handleInvalidRequest (newCtx , message , "Config apply failed" ,
264
+ message .GetConfigApplyRequest ().GetOverview ().GetConfigVersion ().GetInstanceId ())
265
+
266
+ return
267
+ }
229
268
slog .InfoContext (ctx , "Received management plane config apply request" )
230
269
cp .handleConfigApplyRequest (newCtx , message )
231
270
case * mpi.ManagementPlaneRequest_HealthRequest :
232
271
slog .InfoContext (ctx , "Received management plane health request" )
233
272
cp .handleHealthRequest (newCtx )
234
273
case * mpi.ManagementPlaneRequest_ActionRequest :
274
+ if cp .commandServerType != model .Command {
275
+ slog .WarnContext (newCtx , "Auxiliary command server can not perform api action" ,
276
+ "command_server_type" , cp .commandServerType .String ())
277
+ cp .handleInvalidRequest (newCtx , message , "API action failed" ,
278
+ message .GetActionRequest ().GetInstanceId ())
279
+
280
+ return
281
+ }
235
282
slog .InfoContext (ctx , "Received management plane action request" )
236
283
cp .handleAPIActionRequest (newCtx , message )
237
284
default :
@@ -320,6 +367,23 @@ func (cp *CommandPlugin) handleHealthRequest(newCtx context.Context) {
320
367
cp .messagePipe .Process (newCtx , & bus.Message {Topic : bus .DataPlaneHealthRequestTopic })
321
368
}
322
369
370
+ func (cp * CommandPlugin ) handleInvalidRequest (ctx context.Context ,
371
+ request * mpi.ManagementPlaneRequest , message , instanceID string ,
372
+ ) {
373
+ err := cp .commandService .SendDataPlaneResponse (ctx , & mpi.DataPlaneResponse {
374
+ MessageMeta : request .GetMessageMeta (),
375
+ CommandResponse : & mpi.CommandResponse {
376
+ Status : mpi .CommandResponse_COMMAND_STATUS_FAILURE ,
377
+ Message : message ,
378
+ Error : "Can not perform write action as auxiliary command server" ,
379
+ },
380
+ InstanceId : instanceID ,
381
+ })
382
+ if err != nil {
383
+ slog .ErrorContext (ctx , "Unable to send data plane response" , "error" , err )
384
+ }
385
+ }
386
+
323
387
func (cp * CommandPlugin ) createDataPlaneResponse (correlationID string , status mpi.CommandResponse_CommandStatus ,
324
388
message , err string ,
325
389
) * mpi.DataPlaneResponse {
0 commit comments