Skip to content

Commit 0f0c0e2

Browse files
authored
Add nginx plus api actions (#955)
1 parent 2b427d0 commit 0f0c0e2

File tree

14 files changed

+2293
-406
lines changed

14 files changed

+2293
-406
lines changed

api/grpc/mpi/v1/command.pb.go

Lines changed: 477 additions & 266 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/grpc/mpi/v1/command.pb.validate.go

Lines changed: 462 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/grpc/mpi/v1/command.proto

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,11 @@ message APIActionRequest {
204204
message NGINXPlusAction {
205205
// types of actions possible with NGINX Plus API
206206
oneof action {
207-
UpdateHTTPUpstreamServers update_http_upstream_servers = 2;
208-
GetHTTPUpstreamServers get_http_upstream_servers = 3;
207+
UpdateHTTPUpstreamServers update_http_upstream_servers = 1;
208+
GetHTTPUpstreamServers get_http_upstream_servers = 2;
209+
UpdateStreamServers update_stream_servers = 3;
210+
GetUpstreams get_upstreams = 4;
211+
GetStreamUpstreams get_stream_upstreams = 5;
209212
}
210213
}
211214

@@ -223,6 +226,22 @@ message GetHTTPUpstreamServers {
223226
string http_upstream_name = 1;
224227
}
225228

229+
// Update Upstream Stream Servers for an instance
230+
message UpdateStreamServers {
231+
// the name of the upstream stream
232+
string upstream_stream_name = 1;
233+
// a list of upstream stream servers
234+
repeated google.protobuf.Struct servers = 2;
235+
}
236+
237+
// Get Upstreams for an instance
238+
message GetUpstreams {
239+
}
240+
241+
// Get Stream Upstream Servers for an instance
242+
message GetStreamUpstreams {
243+
}
244+
226245
// Request an update on a particular command
227246
message CommandStatusRequest {}
228247

docs/proto/protos.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
- [DataPlaneResponse](#mpi-v1-DataPlaneResponse)
5353
- [FileServer](#mpi-v1-FileServer)
5454
- [GetHTTPUpstreamServers](#mpi-v1-GetHTTPUpstreamServers)
55+
- [GetStreamUpstreams](#mpi-v1-GetStreamUpstreams)
56+
- [GetUpstreams](#mpi-v1-GetUpstreams)
5557
- [HealthRequest](#mpi-v1-HealthRequest)
5658
- [HostInfo](#mpi-v1-HostInfo)
5759
- [Instance](#mpi-v1-Instance)
@@ -74,6 +76,7 @@
7476
- [UpdateDataPlaneStatusRequest](#mpi-v1-UpdateDataPlaneStatusRequest)
7577
- [UpdateDataPlaneStatusResponse](#mpi-v1-UpdateDataPlaneStatusResponse)
7678
- [UpdateHTTPUpstreamServers](#mpi-v1-UpdateHTTPUpstreamServers)
79+
- [UpdateStreamServers](#mpi-v1-UpdateStreamServers)
7780

7881
- [InstanceHealth.InstanceHealthStatus](#mpi-v1-InstanceHealth-InstanceHealthStatus)
7982
- [InstanceMeta.InstanceType](#mpi-v1-InstanceMeta-InstanceType)
@@ -798,6 +801,26 @@ Get HTTP Upstream Servers for an instance
798801

799802

800803

804+
<a name="mpi-v1-GetStreamUpstreams"></a>
805+
806+
### GetStreamUpstreams
807+
Get Stream Upstream Servers for an instance
808+
809+
810+
811+
812+
813+
814+
<a name="mpi-v1-GetUpstreams"></a>
815+
816+
### GetUpstreams
817+
Get Upstreams for an instance
818+
819+
820+
821+
822+
823+
801824
<a name="mpi-v1-HealthRequest"></a>
802825

803826
### HealthRequest
@@ -978,6 +1001,9 @@ Perform an action using the NGINX Plus API on an instance
9781001
| ----- | ---- | ----- | ----------- |
9791002
| update_http_upstream_servers | [UpdateHTTPUpstreamServers](#mpi-v1-UpdateHTTPUpstreamServers) | | |
9801003
| get_http_upstream_servers | [GetHTTPUpstreamServers](#mpi-v1-GetHTTPUpstreamServers) | | |
1004+
| update_stream_servers | [UpdateStreamServers](#mpi-v1-UpdateStreamServers) | | |
1005+
| get_upstreams | [GetUpstreams](#mpi-v1-GetUpstreams) | | |
1006+
| get_stream_upstreams | [GetStreamUpstreams](#mpi-v1-GetStreamUpstreams) | | |
9811007

9821008

9831009

@@ -1137,6 +1163,22 @@ Update HTTP Upstream Servers for an instance
11371163

11381164

11391165

1166+
1167+
<a name="mpi-v1-UpdateStreamServers"></a>
1168+
1169+
### UpdateStreamServers
1170+
Update Upstream Stream Servers for an instance
1171+
1172+
1173+
| Field | Type | Label | Description |
1174+
| ----- | ---- | ----- | ----------- |
1175+
| upstream_stream_name | [string](#string) | | the name of the upstream stream |
1176+
| servers | [google.protobuf.Struct](#google-protobuf-Struct) | repeated | a list of upstream stream servers |
1177+
1178+
1179+
1180+
1181+
11401182

11411183

11421184

internal/datasource/proto/message.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import (
99
"log/slog"
1010
"time"
1111

12+
mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1"
13+
"google.golang.org/protobuf/types/known/timestamppb"
14+
1215
"github.com/google/uuid"
1316
agentUuid "github.com/nginx/agent/v3/pkg/uuid"
1417
)
@@ -29,3 +32,21 @@ func GenerateMessageID() string {
2932

3033
return uuidv7.String()
3134
}
35+
36+
func CreateDataPlaneResponse(correlationID string, status mpi.CommandResponse_CommandStatus,
37+
message, instanceID, err string,
38+
) *mpi.DataPlaneResponse {
39+
return &mpi.DataPlaneResponse{
40+
MessageMeta: &mpi.MessageMeta{
41+
MessageId: GenerateMessageID(),
42+
CorrelationId: correlationID,
43+
Timestamp: timestamppb.Now(),
44+
},
45+
CommandResponse: &mpi.CommandResponse{
46+
Status: status,
47+
Message: message,
48+
Error: err,
49+
},
50+
InstanceId: instanceID,
51+
}
52+
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
// Copyright (c) F5, Inc.
2+
//
3+
// This source code is licensed under the Apache License, Version 2.0 license found in the
4+
// LICENSE file in the root directory of this source tree.
5+
6+
package resource
7+
8+
import (
9+
"context"
10+
"encoding/json"
11+
"log/slog"
12+
13+
mpi "github.com/nginx/agent/v3/api/grpc/mpi/v1"
14+
"github.com/nginx/agent/v3/internal/datasource/proto"
15+
"github.com/nginx/agent/v3/internal/logger"
16+
)
17+
18+
const emptyResponse = "{}"
19+
20+
type APIAction struct {
21+
ResourceService resourceServiceInterface
22+
}
23+
24+
func (a *APIAction) HandleUpdateStreamServersRequest(ctx context.Context, action *mpi.NGINXPlusAction,
25+
instance *mpi.Instance,
26+
) *mpi.DataPlaneResponse {
27+
correlationID := logger.GetCorrelationID(ctx)
28+
instanceID := instance.GetInstanceMeta().GetInstanceId()
29+
30+
add, update, del, err := a.ResourceService.UpdateStreamServers(ctx, instance,
31+
action.GetUpdateStreamServers().GetUpstreamStreamName(), action.GetUpdateStreamServers().GetServers())
32+
if err != nil {
33+
slog.ErrorContext(ctx, "Unable to update stream servers of upstream", "request",
34+
action.GetUpdateHttpUpstreamServers(), "error", err)
35+
36+
return proto.CreateDataPlaneResponse(correlationID, mpi.CommandResponse_COMMAND_STATUS_FAILURE,
37+
"", instanceID, err.Error())
38+
}
39+
40+
slog.DebugContext(ctx, "Successfully updated stream upstream servers", "http_upstream_name",
41+
action.GetUpdateHttpUpstreamServers().GetHttpUpstreamName(), "add", len(add), "update", len(update),
42+
"delete", len(del))
43+
44+
return proto.CreateDataPlaneResponse(correlationID, mpi.CommandResponse_COMMAND_STATUS_OK,
45+
"Successfully updated stream upstream servers", instanceID, "")
46+
}
47+
48+
func (a *APIAction) HandleGetStreamUpstreamsRequest(ctx context.Context,
49+
instance *mpi.Instance,
50+
) *mpi.DataPlaneResponse {
51+
correlationID := logger.GetCorrelationID(ctx)
52+
instanceID := instance.GetInstanceMeta().GetInstanceId()
53+
streamUpstreamsResponse := emptyResponse
54+
55+
streamUpstreams, err := a.ResourceService.GetStreamUpstreams(ctx, instance)
56+
if err != nil {
57+
slog.ErrorContext(ctx, "Unable to get stream upstreams", "error", err)
58+
return proto.CreateDataPlaneResponse(correlationID, mpi.CommandResponse_COMMAND_STATUS_FAILURE,
59+
"", instanceID, err.Error())
60+
}
61+
62+
if streamUpstreams != nil {
63+
streamUpstreamsJSON, jsonErr := json.Marshal(streamUpstreams)
64+
if jsonErr != nil {
65+
slog.ErrorContext(ctx, "Unable to marshal stream upstreams", "err", err)
66+
}
67+
streamUpstreamsResponse = string(streamUpstreamsJSON)
68+
}
69+
70+
return proto.CreateDataPlaneResponse(correlationID, mpi.CommandResponse_COMMAND_STATUS_OK,
71+
streamUpstreamsResponse, instanceID, "")
72+
}
73+
74+
func (a *APIAction) HandleGetUpstreamsRequest(ctx context.Context, instance *mpi.Instance) *mpi.DataPlaneResponse {
75+
correlationID := logger.GetCorrelationID(ctx)
76+
instanceID := instance.GetInstanceMeta().GetInstanceId()
77+
upstreamsResponse := emptyResponse
78+
79+
upstreams, err := a.ResourceService.GetUpstreams(ctx, instance)
80+
if err != nil {
81+
slog.InfoContext(ctx, "Unable to get upstreams", "error", err)
82+
83+
return proto.CreateDataPlaneResponse(correlationID, mpi.CommandResponse_COMMAND_STATUS_FAILURE,
84+
"", instanceID, err.Error())
85+
}
86+
87+
if upstreams != nil {
88+
upstreamsJSON, jsonErr := json.Marshal(upstreams)
89+
if jsonErr != nil {
90+
slog.ErrorContext(ctx, "Unable to marshal upstreams", "err", err)
91+
}
92+
upstreamsResponse = string(upstreamsJSON)
93+
}
94+
95+
return proto.CreateDataPlaneResponse(correlationID, mpi.CommandResponse_COMMAND_STATUS_OK,
96+
upstreamsResponse, instanceID, "")
97+
}
98+
99+
func (a *APIAction) HandleUpdateHTTPUpstreamsRequest(ctx context.Context, action *mpi.NGINXPlusAction,
100+
instance *mpi.Instance,
101+
) *mpi.DataPlaneResponse {
102+
correlationID := logger.GetCorrelationID(ctx)
103+
instanceID := instance.GetInstanceMeta().GetInstanceId()
104+
105+
add, update, del, err := a.ResourceService.UpdateHTTPUpstreamServers(ctx, instance,
106+
action.GetUpdateHttpUpstreamServers().GetHttpUpstreamName(),
107+
action.GetUpdateHttpUpstreamServers().GetServers())
108+
if err != nil {
109+
slog.ErrorContext(ctx, "Unable to update HTTP servers of upstream", "request",
110+
action.GetUpdateHttpUpstreamServers(), "error", err)
111+
112+
return proto.CreateDataPlaneResponse(correlationID, mpi.CommandResponse_COMMAND_STATUS_FAILURE,
113+
"", instanceID, err.Error())
114+
}
115+
116+
slog.DebugContext(ctx, "Successfully updated http upstream servers", "http_upstream_name",
117+
action.GetUpdateHttpUpstreamServers().GetHttpUpstreamName(), "add", len(add), "update", len(update),
118+
"delete", len(del))
119+
120+
return proto.CreateDataPlaneResponse(correlationID, mpi.CommandResponse_COMMAND_STATUS_OK,
121+
"Successfully updated HTTP Upstreams", instanceID, "")
122+
}
123+
124+
func (a *APIAction) HandleGetHTTPUpstreamsServersRequest(ctx context.Context, action *mpi.NGINXPlusAction,
125+
instance *mpi.Instance,
126+
) *mpi.DataPlaneResponse {
127+
correlationID := logger.GetCorrelationID(ctx)
128+
instanceID := instance.GetInstanceMeta().GetInstanceId()
129+
upstreamsResponse := emptyResponse
130+
131+
upstreams, err := a.ResourceService.GetHTTPUpstreamServers(ctx, instance,
132+
action.GetGetHttpUpstreamServers().GetHttpUpstreamName())
133+
if err != nil {
134+
slog.ErrorContext(ctx, "Unable to get HTTP servers of upstream", "error", err)
135+
return proto.CreateDataPlaneResponse(correlationID, mpi.CommandResponse_COMMAND_STATUS_FAILURE,
136+
"", instanceID, err.Error())
137+
}
138+
139+
if upstreams != nil {
140+
upstreamsJSON, jsonErr := json.Marshal(upstreams)
141+
if jsonErr != nil {
142+
slog.ErrorContext(ctx, "Unable to marshal http upstreams", "err", err)
143+
}
144+
upstreamsResponse = string(upstreamsJSON)
145+
}
146+
147+
return proto.CreateDataPlaneResponse(correlationID, mpi.CommandResponse_COMMAND_STATUS_OK,
148+
upstreamsResponse, instanceID, "")
149+
}

0 commit comments

Comments
 (0)