diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 81c11df0d..764341068 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: push: env: - GOLANGCI_LINT_VERSION: 'v1.49.0' + GOLANGCI_LINT_VERSION: 'v1.50.1' NFPM_VERSION: 'v2.18.1' jobs: @@ -13,6 +13,9 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version-file: 'go.mod' - name: Lint Agent Code uses: golangci/golangci-lint-action@v3 with: diff --git a/main.go b/main.go index a02e2ee36..e90b0b7aa 100644 --- a/main.go +++ b/main.go @@ -141,12 +141,8 @@ func handleSignals( }() } -func connectionUnavilable(loadedConfig *config.Config) bool { - return loadedConfig.Server.Host == "" || loadedConfig.Server.GrpcPort == 0 -} - func createGrpcClients(ctx context.Context, loadedConfig *config.Config) (client.Controller, client.Commander, client.MetricReporter) { - if connectionUnavilable(loadedConfig) { + if !loadedConfig.IsGrpcServerConfigured() { log.Infof("GRPC clients not created") return nil, nil, nil } @@ -234,7 +230,7 @@ func loadPlugins(commander client.Commander, binary *core.NginxBinaryType, env * corePlugins = append(corePlugins, plugins.NewAdvancedMetrics(env, loadedConfig)) } - if loadedConfig.NginxAppProtect != (config.NginxAppProtect{}) { + if loadedConfig.IsNginxAppProtectConfigured() { napPlugin, err := plugins.NewNginxAppProtect(loadedConfig, env) if err == nil { corePlugins = append(corePlugins, napPlugin) diff --git a/sdk/proto/command.pb.go b/sdk/proto/command.pb.go index 9cd0046a2..1eb5da172 100644 --- a/sdk/proto/command.pb.go +++ b/sdk/proto/command.pb.go @@ -631,6 +631,7 @@ type NginxConfigStatus struct { CorrelationId string `protobuf:"bytes,1,opt,name=correlation_id,json=correlationId,proto3" json:"correlation_id"` Status NginxConfigStatus_Status `protobuf:"varint,2,opt,name=status,proto3,enum=f5.nginx.agent.sdk.NginxConfigStatus_Status" json:"status"` Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message"` + NginxId string `protobuf:"bytes,4,opt,name=nginx_id,json=nginxId,proto3" json:"nginx_id"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -690,6 +691,13 @@ func (m *NginxConfigStatus) GetMessage() string { return "" } +func (m *NginxConfigStatus) GetNginxId() string { + if m != nil { + return m.NginxId + } + return "" +} + type DataplaneSoftwareHealth struct { // Types that are valid to be assigned to Health: // *DataplaneSoftwareHealth_NginxHealth @@ -1253,103 +1261,103 @@ func init() { func init() { proto.RegisterFile("command.proto", fileDescriptor_213c0bb044472049) } var fileDescriptor_213c0bb044472049 = []byte{ - // 1521 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x4d, 0x6f, 0xdb, 0xc6, - 0x16, 0x25, 0x15, 0xeb, 0xeb, 0x4a, 0xb6, 0x95, 0xb1, 0x93, 0x28, 0x46, 0x60, 0x1a, 0x7c, 0x2f, - 0x2f, 0xce, 0x7b, 0x79, 0x12, 0xea, 0xa0, 0x08, 0x9a, 0xac, 0x24, 0x4b, 0x09, 0x85, 0xc4, 0x92, - 0x31, 0x89, 0x13, 0x20, 0x45, 0x21, 0x30, 0xe2, 0x48, 0x16, 0x6c, 0x91, 0x2c, 0x49, 0x39, 0x71, - 0xd0, 0x7d, 0xd1, 0xa2, 0x9b, 0x2e, 0xba, 0x28, 0xfa, 0x23, 0xfa, 0x37, 0xba, 0xcc, 0xba, 0x0b, - 0xa2, 0xc8, 0x92, 0xbb, 0x6e, 0xda, 0x45, 0x37, 0xc5, 0x7c, 0x50, 0xa2, 0x24, 0x4a, 0x76, 0xea, - 0xa2, 0x1b, 0xce, 0x70, 0x78, 0xee, 0xb9, 0x77, 0xee, 0xcc, 0x9c, 0xb9, 0x12, 0x2c, 0x77, 0xac, - 0xc1, 0x40, 0x37, 0x8d, 0x92, 0xed, 0x58, 0x9e, 0x85, 0x50, 0xf7, 0xe3, 0x92, 0xd9, 0xeb, 0x9b, - 0x6f, 0x4a, 0x7a, 0x8f, 0x98, 0x5e, 0xc9, 0x35, 0x8e, 0x36, 0xa0, 0x67, 0xf5, 0x2c, 0xfe, 0x7d, - 0x23, 0x4f, 0xe1, 0x96, 0x29, 0xde, 0x72, 0x1c, 0xc4, 0x5f, 0xe0, 0xd0, 0x72, 0xc3, 0x7e, 0x8e, - 0x73, 0x8c, 0x6c, 0xcc, 0x6e, 0xbf, 0x27, 0xde, 0x10, 0x39, 0x21, 0xa6, 0xe7, 0x96, 0x59, 0x23, - 0xc6, 0xae, 0x1b, 0x76, 0xdb, 0xb5, 0xba, 0xde, 0x6b, 0xdd, 0x21, 0x6d, 0x83, 0x78, 0x7a, 0xff, - 0xd8, 0x15, 0x9f, 0xb2, 0xa6, 0x6e, 0xf3, 0xae, 0xfa, 0x07, 0x40, 0x7a, 0x97, 0x47, 0x8b, 0xee, - 0xc3, 0xd2, 0x80, 0x78, 0x7a, 0x51, 0xde, 0x92, 0xb7, 0x73, 0x3b, 0x37, 0x4a, 0xb3, 0x61, 0x97, - 0xf6, 0x88, 0xa7, 0x1b, 0xba, 0xa7, 0x57, 0x33, 0x81, 0xaf, 0x30, 0x34, 0x66, 0x4f, 0x54, 0x87, - 0x25, 0xef, 0xd4, 0x26, 0xc5, 0xc4, 0x96, 0xbc, 0xbd, 0xb2, 0x73, 0x2b, 0xce, 0x56, 0xb8, 0x09, - 0xdb, 0x67, 0xa7, 0x36, 0xe1, 0x34, 0xd4, 0x10, 0xb3, 0x27, 0x7a, 0x09, 0xd0, 0x19, 0x18, 0x6d, - 0xd7, 0xd3, 0xbd, 0xa1, 0x5b, 0xbc, 0xc4, 0x02, 0xb9, 0xbd, 0x80, 0xec, 0x29, 0x03, 0x62, 0xe2, - 0xda, 0x96, 0xe9, 0x92, 0xea, 0x4a, 0xe0, 0x2b, 0x11, 0x02, 0x4d, 0xc2, 0xd9, 0xce, 0x40, 0x80, - 0xd0, 0x73, 0xc8, 0x33, 0x96, 0x36, 0x4f, 0x5d, 0x71, 0x89, 0xb1, 0x2b, 0x71, 0xec, 0x4d, 0xfa, - 0xbe, 0xcb, 0x60, 0xd5, 0x42, 0xe0, 0x2b, 0x13, 0x86, 0x9a, 0x84, 0xf9, 0x52, 0x70, 0x00, 0x7a, - 0x03, 0x57, 0xa2, 0x9f, 0xdb, 0x8e, 0x88, 0xa6, 0x98, 0x64, 0x0e, 0x6e, 0x9d, 0xe1, 0x60, 0x14, - 0xfc, 0xf5, 0xc0, 0x57, 0xe2, 0x99, 0x34, 0x09, 0xaf, 0x99, 0xb3, 0x16, 0xd4, 0x33, 0xa3, 0xa4, - 0x78, 0x93, 0x74, 0xbc, 0xb6, 0x43, 0x3e, 0x1f, 0x12, 0xd7, 0x2b, 0xa6, 0xe6, 0x7b, 0xae, 0xd0, - 0xde, 0x2e, 0xc7, 0x63, 0x0e, 0xe7, 0x9e, 0x63, 0x99, 0xa8, 0x67, 0x7d, 0xd6, 0x02, 0x7d, 0x01, - 0x57, 0xa7, 0xf1, 0x62, 0xd2, 0x69, 0xe6, 0x7a, 0xfb, 0x6c, 0xd7, 0x62, 0xd6, 0x1b, 0x81, 0xaf, - 0xcc, 0xe1, 0xd2, 0x24, 0xbc, 0xae, 0xc7, 0xd8, 0x20, 0x0f, 0xd6, 0x47, 0x16, 0x3c, 0x4f, 0x7c, - 0xda, 0x19, 0xe6, 0xfb, 0x3f, 0x8b, 0x7c, 0xb3, 0xf4, 0xf1, 0x59, 0x17, 0x03, 0x5f, 0x89, 0xe5, - 0xd1, 0x24, 0x8c, 0xf4, 0x19, 0x3c, 0xdd, 0x3f, 0x51, 0x74, 0x31, 0x3b, 0x7f, 0xff, 0x44, 0xbc, - 0xf1, 0xfd, 0x13, 0x35, 0xa4, 0xfb, 0x27, 0x42, 0x8f, 0xba, 0x50, 0xa0, 0x47, 0xca, 0x3e, 0xd6, - 0x4d, 0x12, 0xee, 0xfc, 0x1c, 0xe3, 0xfe, 0x57, 0x1c, 0x77, 0x2d, 0xc4, 0xf2, 0x6d, 0x5d, 0x5d, - 0x0f, 0x7c, 0x65, 0x86, 0x40, 0x93, 0xf0, 0xaa, 0x31, 0x09, 0x44, 0x9f, 0x41, 0x9e, 0xe9, 0x43, - 0xdb, 0x21, 0xb6, 0xe5, 0x78, 0xc5, 0xfc, 0xfc, 0x6c, 0x71, 0x39, 0x29, 0xd5, 0x69, 0x83, 0x19, - 0x9a, 0x4f, 0x23, 0x6a, 0x4f, 0xa7, 0x41, 0xc6, 0x00, 0xf4, 0x8d, 0x0c, 0x1b, 0x91, 0x30, 0xa6, - 0x94, 0xa7, 0xb8, 0xcc, 0xbc, 0xdd, 0x59, 0x3c, 0x23, 0x61, 0x54, 0xe3, 0x36, 0xd5, 0xcd, 0xc0, - 0x57, 0x16, 0x70, 0x6a, 0x12, 0x2e, 0x1a, 0x73, 0x6c, 0x27, 0xb3, 0x3a, 0xb4, 0x0d, 0xdd, 0x23, - 0xc5, 0x95, 0x73, 0x64, 0xf5, 0x80, 0x41, 0xa7, 0xb3, 0xca, 0x09, 0x26, 0xb2, 0xca, 0x81, 0xea, - 0x5d, 0xc8, 0x45, 0x04, 0x0d, 0x01, 0xa4, 0x9a, 0x2d, 0xbc, 0x57, 0x79, 0x52, 0x90, 0x50, 0x1e, - 0x32, 0xb5, 0xd6, 0x8b, 0xe6, 0x93, 0x56, 0xa5, 0x56, 0x90, 0xe9, 0x97, 0x83, 0x7d, 0xd6, 0x4f, - 0x54, 0x53, 0xb0, 0x44, 0x79, 0xd4, 0xef, 0x2e, 0xc1, 0x95, 0x58, 0x25, 0x43, 0x9f, 0x42, 0x4a, - 0x6c, 0x05, 0x99, 0x29, 0xea, 0xbd, 0x73, 0x8b, 0xe0, 0xe4, 0x68, 0x15, 0x02, 0x5f, 0x11, 0x54, - 0x58, 0xb4, 0xa8, 0x0f, 0x40, 0x1c, 0xc7, 0x72, 0xda, 0x1d, 0xcb, 0x08, 0x25, 0xfb, 0xfe, 0x07, - 0x3b, 0xa8, 0x53, 0x8a, 0x5d, 0xcb, 0x10, 0xb2, 0x3b, 0x66, 0xc4, 0x59, 0x12, 0x7e, 0x42, 0x37, - 0x21, 0x3d, 0x20, 0xae, 0xab, 0xf7, 0x08, 0x53, 0xf3, 0x6c, 0x35, 0x17, 0xf8, 0x4a, 0x38, 0x84, - 0xc3, 0x0e, 0x52, 0x20, 0xc9, 0x6c, 0x98, 0x28, 0x67, 0xab, 0xd9, 0xc0, 0x57, 0xf8, 0x00, 0xe6, - 0x8d, 0xfa, 0x00, 0x96, 0x27, 0x82, 0x41, 0xab, 0x90, 0xdb, 0xdd, 0xab, 0xb5, 0x0f, 0x9a, 0x8f, - 0x9b, 0xad, 0x17, 0xcd, 0x82, 0x44, 0xf3, 0x4b, 0x07, 0x5a, 0x8f, 0x0b, 0x32, 0x5a, 0x86, 0x2c, - 0xed, 0xd7, 0x31, 0x6e, 0xe1, 0x42, 0x42, 0x2d, 0x43, 0x61, 0x3a, 0x66, 0x0a, 0xaf, 0x63, 0x4c, - 0xe1, 0x12, 0xe5, 0xa2, 0xfd, 0x90, 0x4b, 0x56, 0x7f, 0x48, 0xc2, 0xea, 0xd4, 0x39, 0x43, 0xff, - 0x85, 0xac, 0x7b, 0xea, 0x7a, 0x64, 0xd0, 0xee, 0x1b, 0x6c, 0x51, 0xb2, 0xd5, 0xe5, 0xc0, 0x57, - 0xc6, 0x83, 0x38, 0xc3, 0xbb, 0x0d, 0x03, 0x3d, 0x82, 0x74, 0xb8, 0xef, 0x13, 0x5b, 0x97, 0xb6, - 0x73, 0x3b, 0x5b, 0x73, 0x2f, 0x81, 0x70, 0xaf, 0xb3, 0xbc, 0x08, 0x23, 0x1c, 0x76, 0xe8, 0x95, - 0x4c, 0x2b, 0x00, 0x71, 0x13, 0xc6, 0x5e, 0xc9, 0x9a, 0xe5, 0x7a, 0x0d, 0xb3, 0x6b, 0xf1, 0xbb, - 0x94, 0xa2, 0x31, 0x7b, 0xa2, 0x87, 0x90, 0x3e, 0x24, 0xfa, 0xb1, 0x77, 0xe8, 0x16, 0x93, 0x2c, - 0x88, 0xf9, 0x57, 0x9d, 0xc6, 0x70, 0x3c, 0x06, 0x61, 0x83, 0xc3, 0x0e, 0xfa, 0x7a, 0xf1, 0xc1, - 0x4e, 0x31, 0xee, 0xbf, 0xf5, 0x60, 0x2f, 0x38, 0xd6, 0x5f, 0xc5, 0x07, 0x13, 0x4e, 0x34, 0xcd, - 0x82, 0xf9, 0xdf, 0xb9, 0x82, 0x11, 0x93, 0x9e, 0x17, 0x4b, 0x98, 0x87, 0xd9, 0x58, 0x34, 0x91, - 0x98, 0x93, 0xf0, 0xfa, 0xd5, 0x3b, 0x5e, 0xff, 0xa4, 0xef, 0x9d, 0x86, 0xea, 0x9d, 0x61, 0x51, - 0xcc, 0xbf, 0x7e, 0x2b, 0x02, 0x2f, 0x8e, 0x68, 0xe4, 0xfa, 0x9d, 0x62, 0x12, 0x97, 0xef, 0x24, - 0x5e, 0xfd, 0x56, 0x86, 0xb5, 0x18, 0x1e, 0x64, 0xc3, 0xda, 0x44, 0xf9, 0x10, 0x11, 0x90, 0xdc, - 0xce, 0xcd, 0x33, 0xca, 0x10, 0x11, 0xcb, 0xb5, 0xc0, 0x57, 0xe2, 0x58, 0x34, 0x09, 0x5f, 0x36, - 0x67, 0xd0, 0x19, 0x48, 0x89, 0x98, 0x7e, 0x95, 0xe1, 0xf2, 0x0c, 0x1b, 0xfa, 0x04, 0x56, 0x3a, - 0x96, 0xe3, 0x90, 0x63, 0xdd, 0xeb, 0x5b, 0xe6, 0xf8, 0xe0, 0xa0, 0xc0, 0x57, 0xa6, 0xbe, 0xe0, - 0xe5, 0xc8, 0x7b, 0xc3, 0x40, 0xfb, 0x23, 0x01, 0xe4, 0xfa, 0x74, 0xe7, 0x5c, 0xf1, 0x97, 0x16, - 0xa8, 0xde, 0xf9, 0xa4, 0x48, 0xdd, 0x0e, 0xe7, 0x84, 0x72, 0x90, 0xde, 0xaf, 0x37, 0x6b, 0x8d, - 0xe6, 0xa3, 0x82, 0x84, 0x52, 0x90, 0x60, 0xd2, 0x92, 0x85, 0x64, 0x28, 0x2b, 0xbf, 0xcb, 0x70, - 0x6d, 0xce, 0xae, 0x1a, 0x17, 0x9b, 0x7c, 0x1b, 0x89, 0x45, 0x38, 0xf3, 0x04, 0x46, 0x8a, 0x4d, - 0x6e, 0x38, 0x2a, 0x36, 0x05, 0xef, 0x5b, 0xb8, 0xaa, 0xdb, 0x76, 0x9b, 0x16, 0xef, 0xb4, 0x54, - 0x7a, 0xad, 0x77, 0x43, 0x0f, 0x89, 0x05, 0x35, 0x9f, 0x6d, 0xef, 0x73, 0x83, 0x17, 0x95, 0x87, - 0xc2, 0x13, 0xaf, 0xbb, 0x62, 0xa9, 0x58, 0xd1, 0x37, 0x36, 0xd1, 0xbb, 0xc2, 0x24, 0x03, 0x29, - 0x0e, 0x50, 0x7f, 0x96, 0x23, 0xfa, 0xc8, 0x2f, 0xc2, 0x91, 0x54, 0xc9, 0x7f, 0x41, 0xaa, 0xce, - 0x90, 0x98, 0xc4, 0x3f, 0x29, 0x31, 0xea, 0x1e, 0xac, 0xd6, 0xac, 0xd7, 0xe6, 0xb1, 0xa5, 0x1b, - 0x61, 0xe9, 0x77, 0x81, 0x5f, 0x46, 0xea, 0x97, 0x09, 0x58, 0x8b, 0x29, 0xf7, 0xd1, 0xde, 0xc4, - 0x0d, 0xff, 0x41, 0x3f, 0x73, 0xe2, 0x76, 0x77, 0x03, 0x52, 0x54, 0x3c, 0x2c, 0x53, 0x9c, 0x97, - 0xb3, 0xce, 0x7b, 0x85, 0x81, 0x39, 0x15, 0x37, 0xc4, 0xa2, 0x45, 0xcf, 0x21, 0x27, 0xce, 0x3e, - 0x9d, 0x90, 0xb8, 0x7b, 0xfe, 0x1d, 0x1f, 0x1e, 0x85, 0xd5, 0x88, 0xdb, 0x71, 0xfa, 0xb6, 0x67, - 0x39, 0xd5, 0xd5, 0xc0, 0x57, 0xa2, 0xc6, 0x18, 0xf8, 0x0b, 0x5d, 0x26, 0xf5, 0x37, 0x19, 0xf2, - 0x07, 0x36, 0xcd, 0xab, 0x38, 0x60, 0x17, 0xf9, 0xc1, 0xf9, 0x74, 0x4a, 0x1f, 0xca, 0x71, 0xd6, - 0x51, 0x6f, 0xa5, 0x67, 0x8e, 0x6e, 0xba, 0x5d, 0xe2, 0x2c, 0x90, 0x08, 0x15, 0x52, 0x0e, 0xd1, - 0x5d, 0xcb, 0x14, 0x0a, 0xc1, 0x30, 0x7c, 0x04, 0x8b, 0x56, 0xfd, 0x08, 0x56, 0x26, 0x99, 0xa8, - 0x4e, 0x8c, 0xcb, 0x90, 0x50, 0x27, 0x00, 0x52, 0x0f, 0x2b, 0x8d, 0x27, 0xf5, 0x5a, 0x21, 0xa1, - 0xfe, 0x28, 0x43, 0x96, 0x66, 0x60, 0xf7, 0x70, 0x68, 0x1e, 0xa1, 0x16, 0x3b, 0x46, 0x06, 0x71, - 0x16, 0x2e, 0x3c, 0x85, 0x12, 0x03, 0x13, 0xd7, 0x1a, 0x3a, 0x1d, 0xaa, 0x2a, 0x06, 0x71, 0x78, - 0x3c, 0xdc, 0x58, 0x93, 0xb0, 0xe8, 0x21, 0x8d, 0x57, 0x93, 0x42, 0x01, 0xb6, 0xcf, 0x41, 0xc7, - 0x5e, 0x79, 0x4a, 0xa9, 0xa5, 0x26, 0x61, 0xd6, 0x56, 0xd3, 0x90, 0xec, 0xd0, 0x4f, 0xea, 0x3b, - 0x19, 0xae, 0xc4, 0x86, 0x70, 0xa1, 0x35, 0x53, 0x21, 0xc5, 0xe8, 0xf9, 0x9a, 0x25, 0xf9, 0x74, - 0xf8, 0x08, 0x16, 0x2d, 0xda, 0x86, 0x4c, 0xe7, 0x90, 0x74, 0x8e, 0xdc, 0xe1, 0x40, 0x2c, 0x42, - 0x3e, 0xf0, 0x95, 0xd1, 0x18, 0x1e, 0xf5, 0xd0, 0xff, 0x01, 0x98, 0x4d, 0xdb, 0xed, 0xbf, 0x25, - 0xac, 0x70, 0x4c, 0x8a, 0x3f, 0x00, 0x46, 0xa3, 0x38, 0xcb, 0xfa, 0x4f, 0xfb, 0x6f, 0x89, 0xfa, - 0xbd, 0x0c, 0xeb, 0x71, 0x69, 0xb8, 0xd0, 0x8c, 0x6e, 0xd1, 0x68, 0xa9, 0xb7, 0xbe, 0x21, 0xe6, - 0x24, 0xa2, 0xe5, 0x63, 0x38, 0xcd, 0x7a, 0x0d, 0x03, 0xdd, 0x10, 0x6b, 0x44, 0xa7, 0x94, 0x1f, - 0x67, 0x5e, 0xe4, 0xfd, 0xde, 0x4f, 0xef, 0x37, 0xe5, 0x77, 0xef, 0x37, 0xe5, 0x5f, 0xde, 0x6f, - 0xca, 0x2f, 0x6f, 0xf7, 0xfa, 0xde, 0xe1, 0xf0, 0x55, 0xa9, 0x63, 0x0d, 0xca, 0x2c, 0x92, 0x32, - 0x8b, 0xa4, 0xec, 0x1a, 0x47, 0xe5, 0x93, 0x9d, 0x32, 0xfb, 0xe3, 0xe6, 0x01, 0x7b, 0xbe, 0x4a, - 0xb1, 0xe6, 0xee, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc3, 0xee, 0xd6, 0x35, 0x72, 0x12, 0x00, - 0x00, + // 1535 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xcb, 0x6e, 0xdb, 0x46, + 0x17, 0x26, 0x15, 0xeb, 0x76, 0x24, 0xdb, 0xca, 0xd8, 0x49, 0x14, 0x23, 0x30, 0x0d, 0xfe, 0x7f, + 0x6a, 0xa7, 0x4d, 0x25, 0xd4, 0x41, 0x11, 0x34, 0x59, 0x59, 0x96, 0x13, 0x0a, 0x89, 0x65, 0x63, + 0x12, 0x27, 0x40, 0x8a, 0x42, 0x60, 0xc4, 0x91, 0x4c, 0xd8, 0x22, 0x59, 0x92, 0x72, 0xe2, 0xa0, + 0xfb, 0xa2, 0x45, 0x37, 0x5d, 0x74, 0xd1, 0xf6, 0x21, 0xfa, 0x1a, 0x5d, 0x66, 0xdd, 0x05, 0x51, + 0x64, 0xc9, 0x07, 0x68, 0x17, 0xdd, 0x14, 0x73, 0xa1, 0x44, 0x49, 0x94, 0xec, 0xd4, 0x45, 0x37, + 0x9a, 0xe1, 0xf0, 0x3b, 0xdf, 0xb9, 0xcc, 0xcc, 0x37, 0x43, 0xc1, 0x7c, 0xdb, 0xee, 0xf5, 0x74, + 0xcb, 0xa8, 0x38, 0xae, 0xed, 0xdb, 0x08, 0x75, 0x3e, 0xad, 0x58, 0x5d, 0xd3, 0x7a, 0x5d, 0xd1, + 0xbb, 0xc4, 0xf2, 0x2b, 0x9e, 0x71, 0xb4, 0x02, 0x5d, 0xbb, 0x6b, 0xf3, 0xf7, 0x2b, 0x45, 0x0a, + 0xb7, 0x2d, 0xf1, 0x54, 0xe0, 0x20, 0xfe, 0x00, 0x87, 0xb6, 0x17, 0xf5, 0x0b, 0x9c, 0x63, 0x60, + 0x63, 0x75, 0xcc, 0xae, 0x78, 0x42, 0xe4, 0x84, 0x58, 0xbe, 0x57, 0x65, 0x8d, 0x18, 0xbb, 0x6e, + 0x38, 0x2d, 0xcf, 0xee, 0xf8, 0xaf, 0x74, 0x97, 0xb4, 0x0c, 0xe2, 0xeb, 0xe6, 0xb1, 0x27, 0x5e, + 0xe5, 0x2d, 0xdd, 0xe1, 0x5d, 0xf5, 0x2f, 0x80, 0xec, 0x36, 0x8f, 0x16, 0xdd, 0x83, 0xb9, 0x1e, + 0xf1, 0xf5, 0xb2, 0xbc, 0x26, 0x6f, 0x14, 0x36, 0x6f, 0x54, 0x26, 0xc3, 0xae, 0xec, 0x12, 0x5f, + 0x37, 0x74, 0x5f, 0xaf, 0xe5, 0xc2, 0x40, 0x61, 0x68, 0xcc, 0x7e, 0xd1, 0x0e, 0xcc, 0xf9, 0xa7, + 0x0e, 0x29, 0xa7, 0xd6, 0xe4, 0x8d, 0x85, 0xcd, 0xf5, 0x24, 0x5b, 0xe1, 0x26, 0x6a, 0x9f, 0x9e, + 0x3a, 0x84, 0xd3, 0x50, 0x43, 0xcc, 0x7e, 0xd1, 0x0b, 0x80, 0x76, 0xcf, 0x68, 0x79, 0xbe, 0xee, + 0xf7, 0xbd, 0xf2, 0x25, 0x16, 0xc8, 0xad, 0x19, 0x64, 0x4f, 0x18, 0x10, 0x13, 0xcf, 0xb1, 0x2d, + 0x8f, 0xd4, 0x16, 0xc2, 0x40, 0x89, 0x11, 0x68, 0x12, 0xce, 0xb7, 0x7b, 0x02, 0x84, 0x9e, 0x41, + 0x91, 0xb1, 0xb4, 0x78, 0xe9, 0xca, 0x73, 0x8c, 0x5d, 0x49, 0x62, 0x6f, 0xd2, 0xe7, 0x6d, 0x06, + 0xab, 0x95, 0xc2, 0x40, 0x19, 0x31, 0xd4, 0x24, 0xcc, 0xa7, 0x82, 0x03, 0xd0, 0x6b, 0xb8, 0x12, + 0x7f, 0xdd, 0x72, 0x45, 0x34, 0xe5, 0x34, 0x73, 0xb0, 0x7e, 0x86, 0x83, 0x41, 0xf0, 0xd7, 0xc3, + 0x40, 0x49, 0x66, 0xd2, 0x24, 0xbc, 0x64, 0x4d, 0x5a, 0x50, 0xcf, 0x8c, 0x92, 0xe2, 0x2d, 0xd2, + 0xf6, 0x5b, 0x2e, 0xf9, 0xb2, 0x4f, 0x3c, 0xbf, 0x9c, 0x99, 0xee, 0x79, 0x8b, 0xf6, 0xb6, 0x39, + 0x1e, 0x73, 0x38, 0xf7, 0x9c, 0xc8, 0x44, 0x3d, 0xeb, 0x93, 0x16, 0xe8, 0x2b, 0xb8, 0x3a, 0x8e, + 0x17, 0x49, 0x67, 0x99, 0xeb, 0x8d, 0xb3, 0x5d, 0x8b, 0xac, 0x57, 0xc2, 0x40, 0x99, 0xc2, 0xa5, + 0x49, 0x78, 0x59, 0x4f, 0xb0, 0x41, 0x3e, 0x2c, 0x0f, 0x2c, 0x78, 0x9d, 0x78, 0xda, 0x39, 0xe6, + 0xfb, 0x83, 0x59, 0xbe, 0x59, 0xf9, 0x78, 0xd6, 0xe5, 0x30, 0x50, 0x12, 0x79, 0x34, 0x09, 0x23, + 0x7d, 0x02, 0x4f, 0xd7, 0x4f, 0x1c, 0x5d, 0xce, 0x4f, 0x5f, 0x3f, 0x31, 0x6f, 0x7c, 0xfd, 0xc4, + 0x0d, 0xe9, 0xfa, 0x89, 0xd1, 0xa3, 0x0e, 0x94, 0xe8, 0x96, 0x72, 0x8e, 0x75, 0x8b, 0x44, 0x2b, + 0xbf, 0xc0, 0xb8, 0xff, 0x97, 0xc4, 0x5d, 0x8f, 0xb0, 0x7c, 0x59, 0xd7, 0x96, 0xc3, 0x40, 0x99, + 0x20, 0xd0, 0x24, 0xbc, 0x68, 0x8c, 0x02, 0xd1, 0x17, 0x50, 0x64, 0xfa, 0xd0, 0x72, 0x89, 0x63, + 0xbb, 0x7e, 0xb9, 0x38, 0xbd, 0x5a, 0x5c, 0x4e, 0x2a, 0x3b, 0xb4, 0xc1, 0x0c, 0xcd, 0xd3, 0x88, + 0xdb, 0xd3, 0x34, 0xc8, 0x10, 0x80, 0xbe, 0x93, 0x61, 0x25, 0x16, 0xc6, 0x98, 0xf2, 0x94, 0xe7, + 0x99, 0xb7, 0xdb, 0xb3, 0x33, 0x12, 0x46, 0x75, 0x6e, 0x53, 0x5b, 0x0d, 0x03, 0x65, 0x06, 0xa7, + 0x26, 0xe1, 0xb2, 0x31, 0xc5, 0x76, 0xb4, 0xaa, 0x7d, 0xc7, 0xd0, 0x7d, 0x52, 0x5e, 0x38, 0x47, + 0x55, 0x0f, 0x18, 0x74, 0xbc, 0xaa, 0x9c, 0x60, 0xa4, 0xaa, 0x1c, 0xa8, 0xde, 0x81, 0x42, 0x4c, + 0xd0, 0x10, 0x40, 0xa6, 0xb9, 0x87, 0x77, 0xb7, 0x1e, 0x97, 0x24, 0x54, 0x84, 0x5c, 0x7d, 0xef, + 0x79, 0xf3, 0xf1, 0xde, 0x56, 0xbd, 0x24, 0xd3, 0x37, 0x07, 0xfb, 0xac, 0x9f, 0xaa, 0x65, 0x60, + 0x8e, 0xf2, 0xa8, 0x3f, 0x5c, 0x82, 0x2b, 0x89, 0x4a, 0x86, 0x3e, 0x87, 0x8c, 0x58, 0x0a, 0x32, + 0x53, 0xd4, 0xbb, 0xe7, 0x16, 0xc1, 0xd1, 0xd1, 0x1a, 0x84, 0x81, 0x22, 0xa8, 0xb0, 0x68, 0x91, + 0x09, 0x40, 0x5c, 0xd7, 0x76, 0x5b, 0x6d, 0xdb, 0x88, 0x24, 0xfb, 0xde, 0x7b, 0x3b, 0xd8, 0xa1, + 0x14, 0xdb, 0xb6, 0x21, 0x64, 0x77, 0xc8, 0x88, 0xf3, 0x24, 0x7a, 0x85, 0x6e, 0x42, 0xb6, 0x47, + 0x3c, 0x4f, 0xef, 0x12, 0xa6, 0xe6, 0xf9, 0x5a, 0x21, 0x0c, 0x94, 0x68, 0x08, 0x47, 0x1d, 0xa4, + 0x40, 0x9a, 0xd9, 0x30, 0x51, 0xce, 0xd7, 0xf2, 0x61, 0xa0, 0xf0, 0x01, 0xcc, 0x1b, 0xf5, 0x3e, + 0xcc, 0x8f, 0x04, 0x83, 0x16, 0xa1, 0xb0, 0xbd, 0x5b, 0x6f, 0x1d, 0x34, 0x1f, 0x35, 0xf7, 0x9e, + 0x37, 0x4b, 0x12, 0xad, 0x2f, 0x1d, 0xd8, 0x7b, 0x54, 0x92, 0xd1, 0x3c, 0xe4, 0x69, 0x7f, 0x07, + 0xe3, 0x3d, 0x5c, 0x4a, 0xa9, 0x55, 0x28, 0x8d, 0xc7, 0x4c, 0xe1, 0x3b, 0x18, 0x53, 0xb8, 0x44, + 0xb9, 0x68, 0x3f, 0xe2, 0x92, 0xd5, 0x9f, 0xd3, 0xb0, 0x38, 0xb6, 0xcf, 0xd0, 0x87, 0x90, 0xf7, + 0x4e, 0x3d, 0x9f, 0xf4, 0x5a, 0xa6, 0xc1, 0x26, 0x25, 0x5f, 0x9b, 0x0f, 0x03, 0x65, 0x38, 0x88, + 0x73, 0xbc, 0xdb, 0x30, 0xd0, 0x43, 0xc8, 0x46, 0xeb, 0x3e, 0xb5, 0x76, 0x69, 0xa3, 0xb0, 0xb9, + 0x36, 0xf5, 0x10, 0x88, 0xd6, 0x3a, 0xab, 0x8b, 0x30, 0xc2, 0x51, 0x87, 0x1e, 0xc9, 0xf4, 0x06, + 0x20, 0x4e, 0xc2, 0xc4, 0x23, 0x59, 0xb3, 0x3d, 0xbf, 0x61, 0x75, 0x6c, 0x7e, 0x96, 0x52, 0x34, + 0x66, 0xbf, 0xe8, 0x01, 0x64, 0x0f, 0x89, 0x7e, 0xec, 0x1f, 0x7a, 0xe5, 0x34, 0x0b, 0x62, 0xfa, + 0x51, 0xa7, 0x31, 0x1c, 0x8f, 0x41, 0xd8, 0xe0, 0xa8, 0x83, 0xbe, 0x9d, 0xbd, 0xb1, 0x33, 0x8c, + 0xfb, 0x5f, 0xdd, 0xd8, 0x33, 0xb6, 0xf5, 0x37, 0xc9, 0xc1, 0x44, 0x89, 0x66, 0x59, 0x30, 0x1f, + 0x9d, 0x2b, 0x18, 0x91, 0xf4, 0xb4, 0x58, 0xa2, 0x3a, 0x4c, 0xc6, 0xa2, 0x89, 0xc2, 0x9c, 0x44, + 0xc7, 0xaf, 0xde, 0xf6, 0xcd, 0x13, 0xd3, 0x3f, 0x8d, 0xd4, 0x3b, 0xc7, 0xa2, 0x98, 0x7e, 0xfc, + 0x6e, 0x09, 0xbc, 0xd8, 0xa2, 0xb1, 0xe3, 0x77, 0x8c, 0x49, 0x1c, 0xbe, 0xa3, 0x78, 0xf5, 0x7b, + 0x19, 0x96, 0x12, 0x78, 0x90, 0x03, 0x4b, 0x23, 0xd7, 0x87, 0x98, 0x80, 0x14, 0x36, 0x6f, 0x9e, + 0x71, 0x0d, 0x11, 0xb1, 0x5c, 0x0b, 0x03, 0x25, 0x89, 0x45, 0x93, 0xf0, 0x65, 0x6b, 0x02, 0x9d, + 0x83, 0x8c, 0x88, 0xe9, 0xa7, 0x14, 0x5c, 0x9e, 0x60, 0x43, 0x9f, 0xc1, 0x42, 0xdb, 0x76, 0x5d, + 0x72, 0xac, 0xfb, 0xa6, 0x6d, 0x0d, 0x37, 0x0e, 0x0a, 0x03, 0x65, 0xec, 0x0d, 0x9e, 0x8f, 0x3d, + 0x37, 0x0c, 0xb4, 0x3f, 0x10, 0x40, 0xae, 0x4f, 0xb7, 0xcf, 0x15, 0x7f, 0x65, 0x86, 0xea, 0x9d, + 0x53, 0x8a, 0xd6, 0x21, 0xc7, 0xf3, 0x37, 0x0d, 0xa1, 0x46, 0xc5, 0x30, 0x50, 0x06, 0x63, 0x38, + 0xcb, 0x7a, 0x0d, 0x43, 0xdd, 0x88, 0x92, 0x47, 0x05, 0xc8, 0xee, 0xef, 0x34, 0xeb, 0x8d, 0xe6, + 0xc3, 0x92, 0x84, 0x32, 0x90, 0x62, 0x1a, 0x94, 0x87, 0x74, 0xa4, 0x3f, 0x7f, 0xca, 0x70, 0x6d, + 0xca, 0xf2, 0x1b, 0xde, 0x4a, 0xf9, 0x7a, 0x13, 0xb3, 0x75, 0xe6, 0x56, 0x8d, 0xdd, 0x4a, 0xb9, + 0xe1, 0xe0, 0x56, 0x2a, 0x78, 0xdf, 0xc0, 0x55, 0xdd, 0x71, 0x5a, 0xf4, 0x96, 0x4f, 0xef, 0x54, + 0xaf, 0xf4, 0x4e, 0xe4, 0x21, 0x35, 0xe3, 0x72, 0xe8, 0x38, 0xfb, 0xdc, 0xe0, 0xf9, 0xd6, 0x03, + 0xe1, 0x89, 0x5f, 0xd0, 0x12, 0xa9, 0xd8, 0xed, 0x70, 0x68, 0xa2, 0x77, 0x84, 0x49, 0x0e, 0x32, + 0x1c, 0xa0, 0xfe, 0x26, 0xc7, 0x84, 0x94, 0x9f, 0x98, 0x03, 0x4d, 0x93, 0xff, 0x81, 0xa6, 0x9d, + 0xa1, 0x45, 0xa9, 0xff, 0x52, 0x8b, 0xd4, 0x5d, 0x58, 0xac, 0xdb, 0xaf, 0xac, 0x63, 0x5b, 0x37, + 0xa2, 0x3b, 0xe2, 0x05, 0x3e, 0xa1, 0xd4, 0xaf, 0x53, 0xb0, 0x94, 0xf0, 0x5d, 0x80, 0x76, 0x47, + 0xae, 0x02, 0xef, 0xf5, 0x3d, 0x94, 0xb4, 0x0d, 0x1a, 0x90, 0xa1, 0x2a, 0x63, 0x5b, 0x62, 0x63, + 0x9d, 0x25, 0x0c, 0x5b, 0x0c, 0xcc, 0xa9, 0xb8, 0x21, 0x16, 0x2d, 0x7a, 0x06, 0x05, 0x21, 0x12, + 0x34, 0x21, 0x71, 0x48, 0xfd, 0x3f, 0x39, 0x3c, 0x0a, 0xab, 0x13, 0xaf, 0xed, 0x9a, 0x8e, 0x6f, + 0xbb, 0xb5, 0xc5, 0x30, 0x50, 0xe2, 0xc6, 0x18, 0xf8, 0x03, 0x9d, 0x26, 0xf5, 0x0f, 0x19, 0x8a, + 0x07, 0x0e, 0xad, 0xab, 0xd8, 0x60, 0x17, 0xf9, 0x32, 0x7d, 0x32, 0x26, 0x24, 0xd5, 0x24, 0xeb, + 0xb8, 0xb7, 0xca, 0x53, 0x57, 0xb7, 0xbc, 0x0e, 0x71, 0x67, 0x68, 0x89, 0x0a, 0x19, 0x97, 0xe8, + 0x9e, 0x6d, 0x09, 0x29, 0x61, 0x18, 0x3e, 0x82, 0x45, 0xab, 0x7e, 0x02, 0x0b, 0xa3, 0x4c, 0x54, + 0x27, 0x86, 0xf7, 0x95, 0x48, 0x27, 0x00, 0x32, 0x0f, 0xb6, 0x1a, 0x8f, 0x77, 0xea, 0xa5, 0x94, + 0xfa, 0x8b, 0x0c, 0x79, 0x5a, 0x81, 0xed, 0xc3, 0xbe, 0x75, 0x84, 0xf6, 0xd8, 0x36, 0x32, 0x88, + 0x3b, 0x73, 0xe2, 0x29, 0x94, 0x18, 0x98, 0x78, 0x76, 0xdf, 0x6d, 0x53, 0x55, 0x31, 0x88, 0xcb, + 0xe3, 0xe1, 0xc6, 0x9a, 0x84, 0x45, 0x0f, 0x69, 0xfc, 0xda, 0x29, 0x14, 0x60, 0xe3, 0x1c, 0x74, + 0xec, 0x91, 0x97, 0x94, 0x5a, 0x6a, 0x12, 0x66, 0x6d, 0x2d, 0x0b, 0xe9, 0x36, 0x7d, 0xa5, 0xbe, + 0x95, 0xe1, 0x4a, 0x62, 0x08, 0x17, 0x9a, 0x33, 0x15, 0x32, 0x8c, 0x9e, 0xcf, 0x59, 0x9a, 0xa7, + 0xc3, 0x47, 0xb0, 0x68, 0xd1, 0x06, 0xe4, 0xda, 0x87, 0xa4, 0x7d, 0xe4, 0xf5, 0x7b, 0x62, 0x12, + 0x98, 0x4e, 0x47, 0x63, 0x78, 0xd0, 0x43, 0x1f, 0x03, 0x30, 0x9b, 0x96, 0x67, 0xbe, 0x21, 0x4c, + 0xd3, 0xd3, 0xe2, 0x9f, 0x82, 0xc1, 0x28, 0xce, 0xb3, 0xfe, 0x13, 0xf3, 0x0d, 0x51, 0x7f, 0x94, + 0x61, 0x39, 0xa9, 0x0c, 0x17, 0xca, 0x68, 0x9d, 0x46, 0x4b, 0xbd, 0x99, 0x86, 0xc8, 0x49, 0x44, + 0xcb, 0xc7, 0x70, 0x96, 0xf5, 0x1a, 0x06, 0xba, 0x21, 0xe6, 0x88, 0xa6, 0x54, 0x1c, 0x56, 0x5e, + 0xd4, 0xfd, 0xee, 0xaf, 0xef, 0x56, 0xe5, 0xb7, 0xef, 0x56, 0xe5, 0xdf, 0xdf, 0xad, 0xca, 0x2f, + 0x6e, 0x75, 0x4d, 0xff, 0xb0, 0xff, 0xb2, 0xd2, 0xb6, 0x7b, 0x55, 0x16, 0x49, 0x95, 0x45, 0x52, + 0xf5, 0x8c, 0xa3, 0xea, 0xc9, 0x66, 0x95, 0xfd, 0xc3, 0x73, 0x9f, 0xfd, 0xbe, 0xcc, 0xb0, 0xe6, + 0xce, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc1, 0x1f, 0x57, 0x17, 0x9b, 0x12, 0x00, 0x00, } func (m *Command) Marshal() (dAtA []byte, err error) { @@ -1884,6 +1892,13 @@ func (m *NginxConfigStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.NginxId) > 0 { + i -= len(m.NginxId) + copy(dAtA[i:], m.NginxId) + i = encodeVarintCommand(dAtA, i, uint64(len(m.NginxId))) + i-- + dAtA[i] = 0x22 + } if len(m.Message) > 0 { i -= len(m.Message) copy(dAtA[i:], m.Message) @@ -2653,6 +2668,10 @@ func (m *NginxConfigStatus) Size() (n int) { if l > 0 { n += 1 + l + sovCommand(uint64(l)) } + l = len(m.NginxId) + if l > 0 { + n += 1 + l + sovCommand(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -4007,6 +4026,38 @@ func (m *NginxConfigStatus) Unmarshal(dAtA []byte) error { } m.Message = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NginxId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommand + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommand + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommand + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NginxId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommand(dAtA[iNdEx:]) diff --git a/sdk/proto/command.proto b/sdk/proto/command.proto index 4ae215aa5..feb738c3c 100644 --- a/sdk/proto/command.proto +++ b/sdk/proto/command.proto @@ -103,6 +103,7 @@ message NginxConfigStatus { string correlation_id = 1 [(gogoproto.jsontag) = "correlation_id" ]; Status status = 2 [(gogoproto.jsontag) = "status" ]; string message = 3 [(gogoproto.jsontag) = "message" ]; + string nginx_id = 4 [(gogoproto.jsontag) = "nginx_id" ]; enum Status { PENDING = 0; diff --git a/src/core/config/types.go b/src/core/config/types.go index c65dec245..4ced9dcb3 100644 --- a/src/core/config/types.go +++ b/src/core/config/types.go @@ -38,6 +38,23 @@ type Config struct { NAPMonitoring NAPMonitoring `mapstructure:"nap_monitoring" yaml:"nap_monitoring,omitempty"` } +func (c *Config) IsGrpcServerConfigured() bool { + return c.Server.Host != "" && c.Server.GrpcPort != 0 +} + +func (c *Config) IsNginxAppProtectConfigured() bool { + return c.NginxAppProtect != (NginxAppProtect{}) +} + +func (c *Config) IsFeatureEnabled(feature string) bool { + for _, configFeature := range c.Features { + if configFeature == feature { + return true + } + } + return false +} + type Server struct { Host string `mapstructure:"host" yaml:"-"` GrpcPort int `mapstructure:"grpcPort" yaml:"-"` diff --git a/src/core/nginx.go b/src/core/nginx.go index 93cd0eca4..4b8f1e747 100644 --- a/src/core/nginx.go +++ b/src/core/nginx.go @@ -258,9 +258,11 @@ func (n *NginxBinaryType) ValidateConfig(processId, bin, configLocation string, log.Debugf("Validating config, %s for nginx process, %s", configLocation, processId) response, err := runCmd(bin, "-t", "-c", configLocation) if err != nil { - confFiles, auxFiles, err := sdk.GetNginxConfigFiles(config) - n.writeBackup(config, confFiles, auxFiles) - return fmt.Errorf("error running nginx -t -c %v:\n%s%v", configLocation, response, err) + confFiles, auxFiles, getNginxConfigFilesErr := sdk.GetNginxConfigFiles(config) + if getNginxConfigFilesErr == nil { + n.writeBackup(config, confFiles, auxFiles) + } + return fmt.Errorf("error running nginx -t -c %v:\n%s", configLocation, response) } log.Infof("Config validated:\n%s", response) diff --git a/src/core/topics.go b/src/core/topics.go index 58b00804c..67a6e1ff0 100644 --- a/src/core/topics.go +++ b/src/core/topics.go @@ -52,4 +52,5 @@ const ( ConfigRollbackResponse = "config.rollback.response" DataplaneSoftwareDetailsUpdated = "dataplane.software.details.updated" EnableExtension = "enable.extension" + AgentAPIConfigApplyResponse = "agent.api.config.apply.response" ) diff --git a/src/plugins/agent_api.go b/src/plugins/agent_api.go index 7c6463497..6a871c37c 100644 --- a/src/plugins/agent_api.go +++ b/src/plugins/agent_api.go @@ -12,9 +12,14 @@ import ( "context" "encoding/json" "fmt" + "io" "net/http" + "os" "regexp" + "time" + "github.com/google/uuid" + "github.com/nginx/agent/sdk/v2" "github.com/nginx/agent/sdk/v2/proto" "github.com/nginx/agent/v2/src/core" "github.com/nginx/agent/v2/src/core/config" @@ -24,9 +29,23 @@ import ( log "github.com/sirupsen/logrus" ) +const ( + okStatus = "OK" + pendingStatus = "PENDING" + errorStatus = "ERROR" + unknownStatus = "UNKNOWN" +) + +var ( + instancesRegex = regexp.MustCompile(`^\/nginx[\/]*$`) + configRegex = regexp.MustCompile(`^\/nginx/config[\/]*$`) + configStatusRegex = regexp.MustCompile(`^\/nginx/config/status[\/]*$`) +) + type AgentAPI struct { config *config.Config env core.Environment + pipeline core.MessagePipeInterface server http.Server nginxBinary core.NginxBinary nginxHandler *NginxHandler @@ -34,8 +53,39 @@ type AgentAPI struct { } type NginxHandler struct { - env core.Environment - nginxBinary core.NginxBinary + config *config.Config + env core.Environment + pipeline core.MessagePipeInterface + nginxBinary core.NginxBinary + responseChannel chan *proto.Command_NginxConfigResponse + configResponseStatuses map[string]*proto.NginxConfigStatus +} + +type AgentAPIConfigApplyRequest struct { + correlationId string + config *proto.NginxConfig +} + +type NginxInstanceResponse struct { + NginxId string `json:"nginx_id"` + Message string `json:"message"` + Status string `json:"status"` +} + +type AgentAPIConfigApplyResponse struct { + CorrelationId string `json:"correlation_id"` + NginxInstances []NginxInstanceResponse `json:"nginx_instances"` +} + +type AgentAPICommonResponse struct { + CorrelationId string `json:"correlation_id"` + Message string `json:"message"` +} + +type AgentAPIConfigApplyStatusResponse struct { + CorrelationId string `json:"correlation_id"` + Message string `json:"message"` + Status string `json:"status"` } const ( @@ -43,16 +93,18 @@ const ( jsonMimeType = "application/json" ) -var ( - instancesRegex = regexp.MustCompile(`^\/nginx[\/]*$`) -) - func NewAgentAPI(config *config.Config, env core.Environment, nginxBinary core.NginxBinary) *AgentAPI { - return &AgentAPI{config: config, env: env, nginxBinary: nginxBinary, exporter: prometheus_metrics.NewExporter(&proto.MetricsReport{})} + return &AgentAPI{ + config: config, + env: env, + nginxBinary: nginxBinary, + exporter: prometheus_metrics.NewExporter(&proto.MetricsReport{}), + } } -func (a *AgentAPI) Init(core.MessagePipeInterface) { +func (a *AgentAPI) Init(pipeline core.MessagePipeInterface) { log.Info("Agent API initializing") + a.pipeline = pipeline go a.createHttpServer() } @@ -65,15 +117,30 @@ func (a *AgentAPI) Close() { func (a *AgentAPI) Process(message *core.Message) { log.Tracef("Process function in the agent_api.go, %s %v", message.Topic(), message.Data()) - switch { - case message.Exact(core.MetricReport): - metricReport, ok := message.Data().(*proto.MetricsReport) - if !ok { - log.Warnf("Invalid message received, %T, for topic, %s", message.Data(), message.Topic()) - return + + switch message.Topic() { + case core.AgentAPIConfigApplyResponse: + switch response := message.Data().(type) { + case *proto.Command_NginxConfigResponse: + a.nginxHandler.responseChannel <- response + default: + log.Warnf("Unknown Command_NginxConfigResponse type: %T(%v)", message.Data(), message.Data()) + } + case core.MetricReport: + switch response := message.Data().(type) { + case *proto.MetricsReport: + a.exporter.SetLatestMetricReport(response) + default: + log.Warnf("Unknown MetricReport type: %T(%v)", message.Data(), message.Data()) + } + case core.NginxConfigValidationPending, core.NginxConfigApplyFailed, core.NginxConfigApplySucceeded: + switch response := message.Data().(type) { + case *proto.AgentActivityStatus: + nginxConfigStatus := response.GetNginxConfigStatus() + a.nginxHandler.configResponseStatuses[nginxConfigStatus.GetNginxId()] = nginxConfigStatus + default: + log.Errorf("Expected the type %T but got %T", &proto.AgentActivityStatus{}, response) } - a.exporter.SetLatestMetricReport(metricReport) - return } } func (a *AgentAPI) Info() *core.Info { @@ -81,18 +148,31 @@ func (a *AgentAPI) Info() *core.Info { } func (a *AgentAPI) Subscriptions() []string { - return []string{core.MetricReport} + return []string{ + core.AgentAPIConfigApplyResponse, + core.MetricReport, + core.NginxConfigValidationPending, + core.NginxConfigApplyFailed, + core.NginxConfigApplySucceeded, + } } func (a *AgentAPI) createHttpServer() { + a.nginxHandler = &NginxHandler{ + config: a.config, + pipeline: a.pipeline, + env: a.env, + nginxBinary: a.nginxBinary, + responseChannel: make(chan *proto.Command_NginxConfigResponse), + configResponseStatuses: make(map[string]*proto.NginxConfigStatus), + } + mux := http.NewServeMux() - a.nginxHandler = &NginxHandler{a.env, a.nginxBinary} registerer := prometheus.DefaultRegisterer gatherer := prometheus.DefaultGatherer registerer.MustRegister(a.exporter) mux.Handle("/metrics/", promhttp.HandlerFor(gatherer, promhttp.HandlerOpts{})) - mux.Handle("/nginx/", a.nginxHandler) a.server = http.Server{ @@ -118,11 +198,36 @@ func (a *AgentAPI) createHttpServer() { func (h *NginxHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Header().Set(contentTypeHeader, jsonMimeType) switch { - case r.Method == http.MethodGet && instancesRegex.MatchString(r.URL.Path): - err := sendInstanceDetailsPayload(h.getNginxDetails(), w, r) + case instancesRegex.MatchString(r.URL.Path): + if r.Method != http.MethodGet { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + + err := h.sendInstanceDetailsPayload(w, r) if err != nil { log.Warnf("Failed to send instance details payload: %v", err) } + case configRegex.MatchString(r.URL.Path): + if r.Method != http.MethodPut { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + + err := h.updateConfig(w, r) + if err != nil { + log.Warnf("Failed to update config: %v", err) + } + case configStatusRegex.MatchString(r.URL.Path): + if r.Method != http.MethodGet { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + + err := h.getConfigStatus(w, r) + if err != nil { + log.Warnf("Failed to get config status: %v", err) + } default: w.WriteHeader(http.StatusNotFound) _, err := fmt.Fprint(w, []byte("not found")) @@ -132,7 +237,8 @@ func (h *NginxHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } } -func sendInstanceDetailsPayload(nginxDetails []*proto.NginxDetails, w http.ResponseWriter, r *http.Request) error { +func (h *NginxHandler) sendInstanceDetailsPayload(w http.ResponseWriter, r *http.Request) error { + nginxDetails := h.getNginxDetails() w.WriteHeader(http.StatusOK) if len(nginxDetails) == 0 { @@ -145,20 +251,108 @@ func sendInstanceDetailsPayload(nginxDetails []*proto.NginxDetails, w http.Respo return nil } - respBody := new(bytes.Buffer) - err := json.NewEncoder(respBody).Encode(nginxDetails) + return writeObjectToResponseBody(w, nginxDetails) +} + +func (h *NginxHandler) updateConfig(w http.ResponseWriter, r *http.Request) error { + correlationId := uuid.New().String() + + buf, err := readFileFromRequest(r) if err != nil { - return fmt.Errorf("failed to encode payload: %v", err) + w.WriteHeader(http.StatusBadRequest) + response := AgentAPICommonResponse{ + CorrelationId: correlationId, + Message: err.Error(), + } + return writeObjectToResponseBody(w, response) } - _, err = fmt.Fprint(w, respBody) - if err != nil { - return fmt.Errorf("failed to send payload: %v", err) + nginxDetails := h.getNginxDetails() + + for _, nginxDetail := range nginxDetails { + err := h.applyNginxConfig(nginxDetail, buf, correlationId) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + response := AgentAPICommonResponse{ + CorrelationId: correlationId, + Message: err.Error(), + } + return writeObjectToResponseBody(w, response) + } } + if len(nginxDetails) > 0 { + agentAPIConfigApplyResponse := &AgentAPIConfigApplyResponse{CorrelationId: correlationId, NginxInstances: make([]NginxInstanceResponse, 0)} + + select { + case response := <-h.responseChannel: + nginxResponse := NginxInstanceResponse{ + NginxId: response.NginxConfigResponse.GetConfigData().GetNginxId(), + Message: response.NginxConfigResponse.GetStatus().GetMessage(), + Status: okStatus, + } + + if response.NginxConfigResponse.GetStatus().GetStatus() != proto.CommandStatusResponse_CMD_OK { + w.WriteHeader(http.StatusBadRequest) + nginxResponse.Status = errorStatus + } else { + if response.NginxConfigResponse.GetStatus().GetMessage() == configAppliedProcessedResponse { + w.WriteHeader(http.StatusRequestTimeout) + nginxResponse.Status = pendingStatus + } else { + w.WriteHeader(http.StatusOK) + } + } + + agentAPIConfigApplyResponse.NginxInstances = append(agentAPIConfigApplyResponse.NginxInstances, nginxResponse) + + // If the number of responses match the number of NGINX instances then return a response. + // Otherwise wait until all config apply requests are complete for all NGINX instances. + if len(agentAPIConfigApplyResponse.NginxInstances) == len(nginxDetails) { + return writeObjectToResponseBody(w, agentAPIConfigApplyResponse) + } + + case <-time.After(validationTimeout): + w.WriteHeader(http.StatusRequestTimeout) + agentAPIConfigApplyStatusResponse := AgentAPIConfigApplyStatusResponse{ + CorrelationId: correlationId, + Message: "Pending config apply", + Status: pendingStatus, + } + + return writeObjectToResponseBody(w, agentAPIConfigApplyStatusResponse) + } + } else { + w.WriteHeader(http.StatusInternalServerError) + response := AgentAPICommonResponse{ + CorrelationId: correlationId, + Message: "No NGINX instances found", + } + return writeObjectToResponseBody(w, response) + } + + w.WriteHeader(http.StatusInternalServerError) return nil } +func readFileFromRequest(r *http.Request) (*bytes.Buffer, error) { + err := r.ParseMultipartForm(32 << 20) + if err != nil { + log.Errorf("unable to parse config apply request, %v", err) + } + file, _, err := r.FormFile("file") + if err != nil { + return nil, fmt.Errorf("can't read form file: %v", err) + } + defer file.Close() + + buf := bytes.NewBuffer(nil) + if _, err := io.Copy(buf, file); err != nil { + return nil, fmt.Errorf("can't read file, %v", err) + } + return buf, nil +} + func (h *NginxHandler) getNginxDetails() []*proto.NginxDetails { var nginxDetails []*proto.NginxDetails @@ -169,3 +363,109 @@ func (h *NginxHandler) getNginxDetails() []*proto.NginxDetails { } return nginxDetails } + +func (h *NginxHandler) applyNginxConfig(nginxDetail *proto.NginxDetails, buf *bytes.Buffer, correlationId string) error { + fullFilePath := nginxDetail.ConfPath + + // Create backup of nginx.conf file on host + data, err := os.ReadFile(fullFilePath) + if err != nil { + return fmt.Errorf("unable to read file %s: %v", fullFilePath, err) + } + + protoFile := &proto.File{ + Name: fullFilePath, + Permissions: "0755", + Contents: buf.Bytes(), + } + + configApply, err := sdk.NewConfigApply(protoFile.GetName(), h.config.AllowedDirectoriesMap) + if err != nil { + return fmt.Errorf("unable to write config: %v", err) + } + + // Temporarily write the new nginx.conf to disk + err = h.env.WriteFiles(configApply, []*proto.File{protoFile}, "", h.config.AllowedDirectoriesMap) + if err != nil { + rollbackErr := configApply.Rollback(err) + return fmt.Errorf("config rollback failed: %v", rollbackErr) + } + + // Create NginxConfig object for new nginx.conf + conf, err := h.nginxBinary.ReadConfig(fullFilePath, nginxDetail.NginxId, h.env.GetSystemUUID()) + if err != nil { + rollbackErr := configApply.Rollback(err) + return fmt.Errorf("unable to read config: %v", rollbackErr) + } + + // Write back the original nginx.conf + err = os.WriteFile(fullFilePath, data, 0644) + if err != nil { + rollbackErr := configApply.Rollback(err) + return fmt.Errorf("unable to write file %s: %v", fullFilePath, rollbackErr) + } + + // Send a config apply request to the nginx.go plugin + h.pipeline.Process(core.NewMessage(core.CommNginxConfig, &AgentAPIConfigApplyRequest{correlationId: correlationId, config: conf})) + return nil +} + +func (h *NginxHandler) getConfigStatus(w http.ResponseWriter, r *http.Request) error { + correlationId := r.URL.Query().Get("correlation_id") + + if correlationId == "" { + w.WriteHeader(http.StatusBadRequest) + + agentAPIConfigApplyStatusResponse := AgentAPIConfigApplyStatusResponse{ + CorrelationId: correlationId, + Message: "Missing required query parameter correlation_id", + Status: unknownStatus, + } + + return writeObjectToResponseBody(w, agentAPIConfigApplyStatusResponse) + } + + agentAPIConfigApplyStatusResponse := AgentAPIConfigApplyResponse{ + CorrelationId: correlationId, + NginxInstances: []NginxInstanceResponse{}, + } + + for _, nginxConfigStatus := range h.configResponseStatuses { + if nginxConfigStatus.GetCorrelationId() == correlationId { + nginxInstanceResponse := NginxInstanceResponse{ + NginxId: nginxConfigStatus.GetNginxId(), + Message: nginxConfigStatus.GetMessage(), + Status: nginxConfigStatus.GetStatus().String(), + } + agentAPIConfigApplyStatusResponse.NginxInstances = append(agentAPIConfigApplyStatusResponse.NginxInstances, nginxInstanceResponse) + } + } + + if len(agentAPIConfigApplyStatusResponse.NginxInstances) == 0 { + w.WriteHeader(http.StatusNotFound) + agentAPIConfigApplyStatusResponse := AgentAPIConfigApplyStatusResponse{ + CorrelationId: correlationId, + Message: fmt.Sprintf("Unable to find a config apply request with the correlation_id %s", correlationId), + Status: unknownStatus, + } + + return writeObjectToResponseBody(w, agentAPIConfigApplyStatusResponse) + } + + w.WriteHeader(http.StatusOK) + return writeObjectToResponseBody(w, agentAPIConfigApplyStatusResponse) +} + +func writeObjectToResponseBody(w http.ResponseWriter, response any) error { + respBody := new(bytes.Buffer) + err := json.NewEncoder(respBody).Encode(response) + if err != nil { + return fmt.Errorf("failed to encode payload: %v", err) + } + + _, err = fmt.Fprint(w, respBody) + if err != nil { + return fmt.Errorf("failed to send payload: %v", err) + } + return nil +} diff --git a/src/plugins/agent_api_test.go b/src/plugins/agent_api_test.go index b8c0d2c1d..877643120 100644 --- a/src/plugins/agent_api_test.go +++ b/src/plugins/agent_api_test.go @@ -8,14 +8,19 @@ package plugins import ( + "bytes" "context" "crypto/tls" "crypto/x509" "encoding/json" "fmt" + "io" + "io/fs" "io/ioutil" + "mime/multipart" "net/http" "net/http/httptest" + "path/filepath" "time" "os" @@ -30,8 +35,37 @@ import ( "github.com/nginx/agent/v2/src/core/config" tutils "github.com/nginx/agent/v2/test/utils" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" ) +var ( + nginxConfigContent = tutils.GetDetailsNginxOssConfig() +) + +func TestAgentAPI_Info(t *testing.T) { + agentAPI := AgentAPI{} + info := agentAPI.Info() + + assert.Equal(t, "Agent API Plugin", info.Name()) + assert.Equal(t, "v0.0.1", info.Version()) +} + +func TestAgentAPI_Subscriptions(t *testing.T) { + expectedSubscriptions := []string{ + core.AgentAPIConfigApplyResponse, + core.MetricReport, + core.NginxConfigValidationPending, + core.NginxConfigApplyFailed, + core.NginxConfigApplySucceeded, + } + + agentAPI := AgentAPI{} + subscriptions := agentAPI.Subscriptions() + + assert.Equal(t, expectedSubscriptions, subscriptions) +} + func TestNginxHandler_sendInstanceDetailsPayload(t *testing.T) { tests := []struct { name string @@ -82,7 +116,19 @@ func TestNginxHandler_sendInstanceDetailsPayload(t *testing.T) { path := "/nginx/" req := httptest.NewRequest(http.MethodGet, path, nil) - err := sendInstanceDetailsPayload(tt.nginxDetails, respRec, req) + env := tutils.GetMockEnv() + mockNginxBinary := tutils.NewMockNginxBinary() + processes := []core.Process{} + + for _, nginxDetail := range tt.nginxDetails { + mockNginxBinary.On("GetNginxDetailsFromProcess", mock.Anything).Return(nginxDetail).Once() + processes = append(processes, core.Process{Pid: 1, Name: "12345", IsMaster: true}) + } + + env.On("Processes").Return(processes) + + nginxHandler := NginxHandler{env: env, nginxBinary: mockNginxBinary} + err := nginxHandler.sendInstanceDetailsPayload(respRec, req) assert.NoError(t, err) resp := respRec.Result() @@ -90,7 +136,7 @@ func TestNginxHandler_sendInstanceDetailsPayload(t *testing.T) { var nginxDetailsResponse []*proto.NginxDetails err = json.Unmarshal(respRec.Body.Bytes(), &nginxDetailsResponse) - assert.Nil(t, err) + assert.NoError(t, err) assert.Equal(t, http.StatusOK, resp.StatusCode) assert.True(t, json.Valid(respRec.Body.Bytes())) @@ -99,6 +145,264 @@ func TestNginxHandler_sendInstanceDetailsPayload(t *testing.T) { } } +func TestNginxHandler_updateConfig(t *testing.T) { + conf := &proto.NginxConfig{} + + tests := []struct { + name string + configUpdate string + validationTimeout time.Duration + response *proto.Command_NginxConfigResponse + nginxInstancesPresent bool + expectedStatusCode int + expectedMessage string + expectedStatus string + }{ + { + name: "no nginx instances", + configUpdate: nginxConfigContent, + validationTimeout: 15 * time.Second, + response: nil, + nginxInstancesPresent: false, + expectedStatusCode: 500, + expectedMessage: "No NGINX instances found", + expectedStatus: "", + }, + { + name: "no config apply response", + configUpdate: nginxConfigContent, + validationTimeout: 1 * time.Millisecond, + response: nil, + nginxInstancesPresent: true, + expectedStatusCode: 408, + expectedMessage: "Pending config apply", + expectedStatus: "PENDING", + }, + { + name: "pending config apply response", + configUpdate: nginxConfigContent, + validationTimeout: 15 * time.Second, + response: &proto.Command_NginxConfigResponse{ + NginxConfigResponse: &proto.NginxConfigResponse{ + Status: &proto.CommandStatusResponse{ + Status: proto.CommandStatusResponse_CMD_OK, + Message: configAppliedProcessedResponse, + }, + Action: proto.NginxConfigAction_APPLY, + ConfigData: conf.GetConfigData(), + }, + }, + nginxInstancesPresent: true, + expectedStatusCode: 408, + expectedMessage: "config apply request successfully processed", + expectedStatus: "PENDING", + }, + { + name: "successful config apply response", + configUpdate: nginxConfigContent, + validationTimeout: 15 * time.Second, + response: &proto.Command_NginxConfigResponse{ + NginxConfigResponse: &proto.NginxConfigResponse{ + Status: &proto.CommandStatusResponse{ + Status: proto.CommandStatusResponse_CMD_OK, + Message: configAppliedResponse, + }, + Action: proto.NginxConfigAction_APPLY, + ConfigData: conf.GetConfigData(), + }, + }, + nginxInstancesPresent: true, + expectedStatusCode: 200, + expectedMessage: "config applied successfully", + expectedStatus: "OK", + }, + { + name: "failed config apply response", + configUpdate: nginxConfigContent, + validationTimeout: 15 * time.Second, + response: &proto.Command_NginxConfigResponse{ + NginxConfigResponse: &proto.NginxConfigResponse{ + Status: &proto.CommandStatusResponse{ + Status: proto.CommandStatusResponse_CMD_ERROR, + Message: "config applied failed", + }, + Action: proto.NginxConfigAction_APPLY, + ConfigData: conf.GetConfigData(), + }, + }, + nginxInstancesPresent: true, + expectedStatusCode: 400, + expectedMessage: "config applied failed", + expectedStatus: "ERROR", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + validationTimeout = tt.validationTimeout + w := httptest.NewRecorder() + path := "/nginx/config/" + + file, err := os.CreateTemp(t.TempDir(), "nginx.conf") + require.NoError(t, err) + defer file.Close() + + err = os.WriteFile(file.Name(), []byte(tt.configUpdate), fs.FileMode(os.O_RDWR)) + require.NoError(t, err) + + body := &bytes.Buffer{} + writer := multipart.NewWriter(body) + part, err := writer.CreateFormFile("file", filepath.Base(file.Name())) + require.NoError(t, err) + _, err = io.Copy(part, file) + require.NoError(t, err) + writer.Close() + + r := httptest.NewRequest(http.MethodPut, path, body) + r.Header.Set("Content-Type", writer.FormDataContentType()) + + nginxDetail := &proto.NginxDetails{ + NginxId: "1", Version: "21", ConfPath: file.Name(), ProcessId: "123", StartTime: 1238043824, + BuiltFromSource: false, + LoadableModules: []string{}, + RuntimeModules: []string{}, + Plus: &proto.NginxPlusMetaData{Enabled: true}, + ConfigureArgs: []string{}, + } + + var env *tutils.MockEnvironment + if tt.nginxInstancesPresent { + env = tutils.GetMockEnvWithProcess() + } else { + env = tutils.GetMockEnv() + env.On("Processes", mock.Anything).Return([]core.Process{}) + } + env.On("WriteFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) + + mockNginxBinary := tutils.NewMockNginxBinary() + mockNginxBinary.On("GetNginxDetailsFromProcess", mock.Anything).Return(nginxDetail) + mockNginxBinary.On("ReadConfig", mock.Anything, mock.Anything, mock.Anything).Return(conf, nil) + + pipeline := core.NewMessagePipe(context.TODO()) + + h := &NginxHandler{ + config: config.Defaults, + env: env, + pipeline: pipeline, + nginxBinary: mockNginxBinary, + responseChannel: make(chan *proto.Command_NginxConfigResponse), + } + + if tt.response != nil { + go func() { h.responseChannel <- tt.response }() + } + + err = h.updateConfig(w, r) + assert.NoError(t, err) + + assert.Equal(t, tt.expectedStatusCode, w.Result().StatusCode) + + resp := w.Result() + defer resp.Body.Close() + + if tt.response == nil { + result := &AgentAPIConfigApplyStatusResponse{} + err = json.NewDecoder(w.Body).Decode(result) + assert.NoError(t, err) + assert.Equal(t, tt.expectedMessage, result.Message) + assert.Equal(t, tt.expectedStatus, result.Status) + } else { + result := &AgentAPIConfigApplyResponse{} + err = json.NewDecoder(w.Body).Decode(result) + assert.NoError(t, err) + assert.Equal(t, tt.expectedMessage, result.NginxInstances[0].Message) + assert.Equal(t, tt.expectedStatus, result.NginxInstances[0].Status) + } + + }) + } +} + +func TestNginxHandler_getConfigStatus(t *testing.T) { + tests := []struct { + name string + url string + configResponseStatuses map[string]*proto.NginxConfigStatus + expectedStatusCode int + expectedMessage string + expectedStatus string + }{ + { + name: "no query parameter", + url: "/nginx/config/status/", + configResponseStatuses: make(map[string]*proto.NginxConfigStatus), + expectedStatusCode: 400, + expectedMessage: "Missing required query parameter correlation_id", + expectedStatus: "UNKNOWN", + }, + { + name: "no matching correlation_id", + url: "/nginx/config/status/?correlation_id=123", + configResponseStatuses: make(map[string]*proto.NginxConfigStatus), + expectedStatusCode: 404, + expectedMessage: "Unable to find a config apply request with the correlation_id 123", + expectedStatus: "UNKNOWN", + }, + { + name: "found matching correlation_id", + url: "/nginx/config/status/?correlation_id=123", + configResponseStatuses: map[string]*proto.NginxConfigStatus{ + "12345": { + CorrelationId: "123", + Status: proto.NginxConfigStatus_OK, + Message: "config applied successfully", + NginxId: "12345", + }, + }, + expectedStatusCode: 200, + expectedMessage: "config applied successfully", + expectedStatus: "OK", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodGet, tt.url, nil) + h := &NginxHandler{ + config: config.Defaults, + env: tutils.GetMockEnv(), + pipeline: core.NewMessagePipe(context.TODO()), + nginxBinary: tutils.NewMockNginxBinary(), + responseChannel: make(chan *proto.Command_NginxConfigResponse), + configResponseStatuses: tt.configResponseStatuses, + } + + err := h.getConfigStatus(w, r) + assert.NoError(t, err) + + assert.Equal(t, tt.expectedStatusCode, w.Result().StatusCode) + + resp := w.Result() + defer resp.Body.Close() + + if len(tt.configResponseStatuses) > 0 { + result := &AgentAPIConfigApplyResponse{} + err = json.NewDecoder(w.Body).Decode(result) + assert.NoError(t, err) + assert.Equal(t, tt.expectedMessage, result.NginxInstances[0].Message) + assert.Equal(t, tt.expectedStatus, result.NginxInstances[0].Status) + assert.Equal(t, "12345", result.NginxInstances[0].NginxId) + + } else { + result := &AgentAPIConfigApplyStatusResponse{} + err = json.NewDecoder(w.Body).Decode(result) + assert.NoError(t, err) + assert.Equal(t, tt.expectedMessage, result.Message) + assert.Equal(t, tt.expectedStatus, result.Status) + } + }) + } +} + func TestProcess_metricReport(t *testing.T) { conf := &config.Config{ AgentAPI: config.AgentAPI{ diff --git a/src/plugins/dataplane_status.go b/src/plugins/dataplane_status.go index 255ff91c8..dc6a433f2 100644 --- a/src/plugins/dataplane_status.go +++ b/src/plugins/dataplane_status.go @@ -23,25 +23,25 @@ import ( ) type DataPlaneStatus struct { - messagePipeline core.MessagePipeInterface - ctx context.Context - sendStatus chan bool - healthTicker *time.Ticker - interval time.Duration - meta *proto.Metadata - binary core.NginxBinary - env core.Environment - version string - tags *[]string - configDirs string - lastSendDetails time.Time - envHostInfo *proto.HostInfo - statusUrls map[string]string - reportInterval time.Duration - napDetails *proto.DataplaneSoftwareDetails_AppProtectWafDetails - agentActivityStatuses []*proto.AgentActivityStatus - napDetailsMutex sync.RWMutex - napHealth *proto.DataplaneSoftwareHealth_AppProtectWafHealth + messagePipeline core.MessagePipeInterface + ctx context.Context + sendStatus chan bool + healthTicker *time.Ticker + interval time.Duration + meta *proto.Metadata + binary core.NginxBinary + env core.Environment + version string + tags *[]string + configDirs string + lastSendDetails time.Time + envHostInfo *proto.HostInfo + statusUrls map[string]string + reportInterval time.Duration + napDetails *proto.DataplaneSoftwareDetails_AppProtectWafDetails + nginxConfigActivityStatuses map[string]*proto.AgentActivityStatus + napDetailsMutex sync.RWMutex + napHealth *proto.DataplaneSoftwareHealth_AppProtectWafHealth } const ( @@ -56,18 +56,19 @@ func NewDataPlaneStatus(config *config.Config, meta *proto.Metadata, binary core log.Warnf("interval set to %s, provided value (%s) less than minimum", pollInt, config.Dataplane.Status.PollInterval) } return &DataPlaneStatus{ - sendStatus: make(chan bool), - healthTicker: time.NewTicker(pollInt), - interval: pollInt, - meta: meta, - binary: binary, - env: env, - version: version, - tags: &config.Tags, - configDirs: config.ConfigDirs, - statusUrls: make(map[string]string), - reportInterval: config.Dataplane.Status.ReportInterval, - napDetailsMutex: sync.RWMutex{}, + sendStatus: make(chan bool), + healthTicker: time.NewTicker(pollInt), + interval: pollInt, + meta: meta, + binary: binary, + env: env, + version: version, + tags: &config.Tags, + configDirs: config.ConfigDirs, + statusUrls: make(map[string]string), + reportInterval: config.Dataplane.Status.ReportInterval, + napDetailsMutex: sync.RWMutex{}, + nginxConfigActivityStatuses: make(map[string]*proto.AgentActivityStatus), // Intentionally empty as it will be set later napDetails: nil, napHealth: &proto.DataplaneSoftwareHealth_AppProtectWafHealth{}, @@ -112,7 +113,7 @@ func (dps *DataPlaneStatus) Process(msg *core.Message) { log.Tracef("DataplaneStatus: %T message from topic %s received", msg.Data(), msg.Topic()) switch data := msg.Data().(type) { case *proto.AgentActivityStatus: - dps.updateAgentActivityStatuses(data) + dps.updateNginxConfigActivityStatuses(data) default: log.Errorf("Expected the type %T but got %T", &proto.AgentActivityStatus{}, data) } @@ -121,9 +122,8 @@ func (dps *DataPlaneStatus) Process(msg *core.Message) { log.Tracef("DataplaneStatus: %T message from topic %s received", msg.Data(), msg.Topic()) switch data := msg.Data().(type) { case *proto.AgentActivityStatus: - dps.updateAgentActivityStatuses(data) + dps.updateNginxConfigActivityStatuses(data) dps.sendDataplaneStatus(dps.messagePipeline, false) - dps.removeAgentActivityStatus(data) default: log.Errorf("Expected the type %T but got %T", &proto.AgentActivityStatus{}, data) } @@ -140,34 +140,10 @@ func (dps *DataPlaneStatus) Subscriptions() []string { } } -func (dps *DataPlaneStatus) updateAgentActivityStatuses(newAgentActivityStatus *proto.AgentActivityStatus) { - log.Tracef("DataplaneStatus: Adding %v to agentActivityStatuses", newAgentActivityStatus) +func (dps *DataPlaneStatus) updateNginxConfigActivityStatuses(newAgentActivityStatus *proto.AgentActivityStatus) { + log.Tracef("DataplaneStatus: Updating nginxConfigActivityStatuses with %v", newAgentActivityStatus) if _, ok := newAgentActivityStatus.GetStatus().(*proto.AgentActivityStatus_NginxConfigStatus); ok { - foundExistingNginxStatus := false - for index, agentActivityStatus := range dps.agentActivityStatuses { - if _, ok := agentActivityStatus.GetStatus().(*proto.AgentActivityStatus_NginxConfigStatus); ok { - dps.agentActivityStatuses[index] = newAgentActivityStatus - log.Tracef("DataplaneStatus: Updated agentActivityStatus with new status %v", newAgentActivityStatus) - foundExistingNginxStatus = true - } - } - - if !foundExistingNginxStatus { - dps.agentActivityStatuses = append(dps.agentActivityStatuses, newAgentActivityStatus) - log.Tracef("DataplaneStatus: Added new status %v to agentActivityStatus", newAgentActivityStatus) - } - } -} - -func (dps *DataPlaneStatus) removeAgentActivityStatus(agentActivityStatus *proto.AgentActivityStatus) { - log.Tracef("DataplaneStatus: Removing %v from agentActivityStatuses", agentActivityStatus) - if _, ok := agentActivityStatus.GetStatus().(*proto.AgentActivityStatus_NginxConfigStatus); ok { - for index, agentActivityStatus := range dps.agentActivityStatuses { - if _, ok := agentActivityStatus.GetStatus().(*proto.AgentActivityStatus_NginxConfigStatus); ok { - dps.agentActivityStatuses = append(dps.agentActivityStatuses[:index], dps.agentActivityStatuses[index+1:]...) - log.Tracef("DataplaneStatus: Removed %v from agentActivityStatus", agentActivityStatus) - } - } + dps.nginxConfigActivityStatuses[newAgentActivityStatus.GetNginxConfigStatus().GetNginxId()] = newAgentActivityStatus } } @@ -205,12 +181,18 @@ func (dps *DataPlaneStatus) dataplaneStatus(forceDetails bool) *proto.DataplaneS processes := dps.env.Processes() log.Tracef("dataplaneStatus: processes %v", processes) forceDetails = forceDetails || time.Now().UTC().Add(-dps.reportInterval).After(dps.lastSendDetails) + + agentActivityStatuses := []*proto.AgentActivityStatus{} + for _, nginxConfigActivityStatus := range dps.nginxConfigActivityStatuses { + agentActivityStatuses = append(agentActivityStatuses, nginxConfigActivityStatus) + } + return &proto.DataplaneStatus{ Host: dps.hostInfo(forceDetails), Details: dps.detailsForProcess(processes, forceDetails), Healths: dps.healthForProcess(processes), DataplaneSoftwareDetails: dps.dataplaneSoftwareDetails(), - AgentActivityStatus: dps.agentActivityStatuses, + AgentActivityStatus: agentActivityStatuses, } } diff --git a/src/plugins/dataplane_status_test.go b/src/plugins/dataplane_status_test.go index a7a54ae39..6e06edacb 100644 --- a/src/plugins/dataplane_status_test.go +++ b/src/plugins/dataplane_status_test.go @@ -36,7 +36,9 @@ func TestDataPlaneStatus(t *testing.T) { expectedMessage: core.NewMessage(core.CommStatus, &proto.Command{ Meta: nil, Data: &proto.Command_DataplaneStatus{ - DataplaneStatus: &proto.DataplaneStatus{}, + DataplaneStatus: &proto.DataplaneStatus{ + AgentActivityStatus: []*proto.AgentActivityStatus{}, + }, }, }), }, diff --git a/src/plugins/nginx.go b/src/plugins/nginx.go index 334c9653b..a111b4019 100644 --- a/src/plugins/nginx.go +++ b/src/plugins/nginx.go @@ -31,23 +31,28 @@ import ( "github.com/nginx/agent/v2/src/extensions/nginx-app-protect/nap" ) +const ( + configAppliedProcessedResponse = "config apply request successfully processed" + configAppliedResponse = "config applied successfully" +) + var ( validationTimeout = 15 * time.Second ) // Nginx is the metadata of our nginx binary type Nginx struct { - messagePipeline core.MessagePipeInterface - nginxBinary core.NginxBinary - processes []core.Process - env core.Environment - cmdr client.Commander - config *config.Config - isNAPEnabled bool - isConfUploadEnabled bool - configApplyStatusChannel chan *proto.Command_NginxConfigResponse - wafVersion string - wafLocation string + messagePipeline core.MessagePipeInterface + nginxBinary core.NginxBinary + processes []core.Process + env core.Environment + cmdr client.Commander + config *config.Config + isNAPEnabled bool + isFeatureNginxConfigEnabled bool + configApplyStatusChannel chan *proto.Command_NginxConfigResponse + wafVersion string + wafLocation string } type ConfigRollbackResponse struct { @@ -74,23 +79,19 @@ type NginxConfigValidationResponse struct { } func NewNginx(cmdr client.Commander, nginxBinary core.NginxBinary, env core.Environment, loadedConfig *config.Config) *Nginx { - var isNAPEnabled bool - if loadedConfig.NginxAppProtect != (config.NginxAppProtect{}) { - isNAPEnabled = true - } - - isConfUploadEnabled := isConfUploadEnabled(loadedConfig) + isNAPEnabled := loadedConfig.IsNginxAppProtectConfigured() + isFeatureNginxConfigEnabled := loadedConfig.IsFeatureEnabled(agent_config.FeatureNginxConfig) return &Nginx{ - nginxBinary: nginxBinary, - processes: env.Processes(), - env: env, - cmdr: cmdr, - config: loadedConfig, - isNAPEnabled: isNAPEnabled, - isConfUploadEnabled: isConfUploadEnabled, - configApplyStatusChannel: make(chan *proto.Command_NginxConfigResponse, 1), - wafLocation: nap.APP_PROTECT_METADATA_FILE_PATH, + nginxBinary: nginxBinary, + processes: env.Processes(), + env: env, + cmdr: cmdr, + config: loadedConfig, + isNAPEnabled: isNAPEnabled, + isFeatureNginxConfigEnabled: isFeatureNginxConfigEnabled, + configApplyStatusChannel: make(chan *proto.Command_NginxConfigResponse, 1), + wafLocation: nap.APP_PROTECT_METADATA_FILE_PATH, } } @@ -114,7 +115,13 @@ func (n *Nginx) Process(message *core.Message) { switch cmd := message.Data().(type) { case *proto.Command: n.processCmd(cmd) + case *AgentAPIConfigApplyRequest: + status := n.writeConfigAndReloadNginx(cmd.correlationId, cmd.config, proto.NginxConfigAction_APPLY) + if status.NginxConfigResponse.GetStatus().GetMessage() != configAppliedProcessedResponse { + n.messagePipeline.Process(core.NewMessage(core.AgentAPIConfigApplyResponse, status)) + } } + case core.NginxConfigUpload: switch cfg := message.Data().(type) { case *proto.ConfigDescriptor: @@ -187,7 +194,7 @@ func (n *Nginx) Subscriptions() []string { func (n *Nginx) uploadConfig(config *proto.ConfigDescriptor, messageId string) error { log.Debugf("Uploading config for %v", config) - if !n.isConfUploadEnabled { + if !n.isFeatureNginxConfigEnabled { log.Info("unable to upload config as nginx-config feature is disabled") return nil } @@ -245,7 +252,7 @@ func (n *Nginx) processCmd(cmd *proto.Command) { switch commandData.NginxConfig.Action { case proto.NginxConfigAction_APPLY, proto.NginxConfigAction_FORCE: - if n.isConfUploadEnabled { + if n.isFeatureNginxConfigEnabled { status = n.applyConfig(cmd, commandData) } else { log.Warnf("unable to upload config as nginx-config feature is disabled") @@ -279,20 +286,9 @@ func (n *Nginx) processCmd(cmd *proto.Command) { func (n *Nginx) applyConfig(cmd *proto.Command, cfg *proto.Command_NginxConfig) (status *proto.Command_NginxConfigResponse) { log.Debugf("Applying config for message id, %s", cmd.GetMeta().MessageId) - - n.messagePipeline.Process(core.NewMessage(core.NginxConfigValidationPending, &proto.AgentActivityStatus{ - Status: &proto.AgentActivityStatus_NginxConfigStatus{ - NginxConfigStatus: &proto.NginxConfigStatus{ - CorrelationId: cmd.Meta.MessageId, - Status: proto.NginxConfigStatus_PENDING, - Message: "config apply pending", - }, - }, - })) - status = &proto.Command_NginxConfigResponse{ NginxConfigResponse: &proto.NginxConfigResponse{ - Status: newOKStatus("config apply request successfully processed").CmdStatus, + Status: newOKStatus(configAppliedProcessedResponse).CmdStatus, Action: proto.NginxConfigAction_APPLY, ConfigData: cfg.NginxConfig.ConfigData, }, @@ -304,13 +300,44 @@ func (n *Nginx) applyConfig(cmd *proto.Command, cfg *proto.Command_NginxConfig) return status } + if err != nil { + status.NginxConfigResponse.Status = newErrStatus("Config apply failed: " + err.Error()).CmdStatus + return status + } + + status = n.writeConfigAndReloadNginx(cmd.Meta.MessageId, config, cmd.GetNginxConfig().GetAction()) + + log.Debug("Config Apply Complete") + return status +} + +func (n *Nginx) writeConfigAndReloadNginx(correlationId string, config *proto.NginxConfig, action proto.NginxConfigAction) *proto.Command_NginxConfigResponse { + status := &proto.Command_NginxConfigResponse{ + NginxConfigResponse: &proto.NginxConfigResponse{ + Status: newOKStatus(configAppliedProcessedResponse).CmdStatus, + Action: proto.NginxConfigAction_APPLY, + ConfigData: config.ConfigData, + }, + } + + n.messagePipeline.Process(core.NewMessage(core.NginxConfigValidationPending, &proto.AgentActivityStatus{ + Status: &proto.AgentActivityStatus_NginxConfigStatus{ + NginxConfigStatus: &proto.NginxConfigStatus{ + CorrelationId: correlationId, + Status: proto.NginxConfigStatus_PENDING, + Message: "config apply pending", + NginxId: config.GetConfigData().GetNginxId(), + }, + }, + })) + if config.GetConfigData().GetNginxId() == "" { status.NginxConfigResponse.Status = newErrStatus(fmt.Sprintf("Config apply failed (preflight): no Nginx Id in ConfigDescriptor %v", config.GetConfigData())).CmdStatus return status } - if cmd.GetNginxConfig().GetAction() != proto.NginxConfigAction_FORCE { - if isNapInPayload(config.GetDirectoryMap(), cmd.GetNginxConfig().GetAction(), n.wafLocation) { + if action != proto.NginxConfigAction_FORCE { + if isNapInPayload(config.GetDirectoryMap(), action, n.wafLocation) { if aux := config.GetZaux(); aux != nil && len(aux.Contents) > 0 { auxFiles, err := zip.UnPack(aux) if err != nil { @@ -340,12 +367,12 @@ func (n *Nginx) applyConfig(cmd *proto.Command, cfg *proto.Command_NginxConfig) n.messagePipeline.Process(core.NewMessage(core.FileWatcherEnabled, false)) nginx := n.nginxBinary.GetNginxDetailsByID(config.GetConfigData().GetNginxId()) - if nginx == nil || nginx == (&proto.NginxDetails{}) { message := fmt.Sprintf("Config apply failed (preflight): no Nginx instance found for %v", config.GetConfigData().GetNginxId()) return n.handleErrorStatus(status, message) } + log.Debugf("WriteConfig start %v", config) configApply, err := n.nginxBinary.WriteConfig(config) if err != nil { if configApply != nil { @@ -358,7 +385,7 @@ func (n *Nginx) applyConfig(cmd *proto.Command, cfg *proto.Command_NginxConfig) configRollbackResponse := ConfigRollbackResponse{ succeeded: succeeded, - correlationId: cmd.Meta.MessageId, + correlationId: correlationId, timestamp: types.TimestampNow(), nginxDetails: nginx, } @@ -366,21 +393,10 @@ func (n *Nginx) applyConfig(cmd *proto.Command, cfg *proto.Command_NginxConfig) } message := fmt.Sprintf("Config apply failed (write): " + err.Error()) - - n.messagePipeline.Process(core.NewMessage(core.NginxConfigApplyFailed, &proto.AgentActivityStatus{ - Status: &proto.AgentActivityStatus_NginxConfigStatus{ - NginxConfigStatus: &proto.NginxConfigStatus{ - CorrelationId: cmd.Meta.MessageId, - Status: proto.NginxConfigStatus_ERROR, - Message: message, - }, - }, - })) - return n.handleErrorStatus(status, message) } - go n.validateConfig(nginx, cmd.Meta.MessageId, config, configApply) + go n.validateConfig(nginx, correlationId, config, configApply) // If the NGINX config can be validated with the validationTimeout the result will be returned straight away. // This is timeout is temporary to ensure we support backwards compatibility. In a future release this timeout @@ -389,7 +405,7 @@ func (n *Nginx) applyConfig(cmd *proto.Command, cfg *proto.Command_NginxConfig) case result := <-n.configApplyStatusChannel: return result case <-time.After(validationTimeout): - log.Debugf("Validation of the NGINX config in taking longer than the validationTimeout %s", validationTimeout) + log.Errorf("Validation of the NGINX config in taking longer than the validationTimeout %s", validationTimeout) return status } } @@ -445,7 +461,7 @@ func (n *Nginx) validateConfig(nginx *proto.NginxDetails, correlationId string, } func (n *Nginx) completeConfigApply(response *NginxConfigValidationResponse) *proto.Command_NginxConfigResponse { - nginxConfigStatusMessage := "Config applied successfully" + nginxConfigStatusMessage := configAppliedResponse if response.configApply != nil { if err := response.configApply.Complete(); err != nil { nginxConfigStatusMessage = fmt.Sprintf("Config complete failed: %v", err) @@ -453,31 +469,35 @@ func (n *Nginx) completeConfigApply(response *NginxConfigValidationResponse) *pr } } - uploadResponse := &proto.Command_NginxConfigResponse{ - NginxConfigResponse: &proto.NginxConfigResponse{ - Action: proto.NginxConfigAction_UNKNOWN, - Status: newOKStatus("config uploaded status").CmdStatus, - ConfigData: nil, - }, - } + // Upload NGINX config only if GPRC server is configured + if n.config.IsGrpcServerConfigured() { + uploadResponse := &proto.Command_NginxConfigResponse{ + NginxConfigResponse: &proto.NginxConfigResponse{ + Action: proto.NginxConfigAction_UNKNOWN, + Status: newOKStatus("config uploaded status").CmdStatus, + ConfigData: nil, + }, + } - err := n.uploadConfig( - &proto.ConfigDescriptor{ - SystemId: n.env.GetSystemUUID(), - NginxId: response.config.GetConfigData().GetNginxId(), - }, - response.correlationId, - ) - if err != nil { - uploadResponse.NginxConfigResponse.Status = newErrStatus("Config uploaded error: " + err.Error()).CmdStatus - nginxConfigStatusMessage = fmt.Sprintf("Config uploaded error: %v", err) - log.Errorf(nginxConfigStatusMessage) - } + err := n.uploadConfig( + &proto.ConfigDescriptor{ + SystemId: n.env.GetSystemUUID(), + NginxId: response.config.GetConfigData().GetNginxId(), + }, + response.correlationId, + ) + if err != nil { + uploadResponse.NginxConfigResponse.Status = newErrStatus("Config uploaded error: " + err.Error()).CmdStatus + nginxConfigStatusMessage = fmt.Sprintf("Config uploaded error: %v", err) + log.Errorf(nginxConfigStatusMessage) + } - uploadResponseCommand := &proto.Command{Meta: grpc.NewMessageMeta(response.correlationId)} - uploadResponseCommand.Data = uploadResponse + uploadResponseCommand := &proto.Command{Meta: grpc.NewMessageMeta(response.correlationId)} + uploadResponseCommand.Data = uploadResponse + + n.messagePipeline.Process(core.NewMessage(core.CommResponse, uploadResponseCommand)) + } - n.messagePipeline.Process(core.NewMessage(core.CommResponse, uploadResponseCommand)) log.Debug("Enabling file watcher") n.messagePipeline.Process(core.NewMessage(core.FileWatcherEnabled, true)) @@ -502,6 +522,7 @@ func (n *Nginx) completeConfigApply(response *NginxConfigValidationResponse) *pr CorrelationId: response.correlationId, Status: proto.NginxConfigStatus_OK, Message: nginxConfigStatusMessage, + NginxId: response.config.GetConfigData().GetNginxId(), }, }, } @@ -510,7 +531,7 @@ func (n *Nginx) completeConfigApply(response *NginxConfigValidationResponse) *pr status := &proto.Command_NginxConfigResponse{ NginxConfigResponse: &proto.NginxConfigResponse{ - Status: newOKStatus("config apply request successfully processed").CmdStatus, + Status: newOKStatus(nginxConfigStatusMessage).CmdStatus, Action: proto.NginxConfigAction_APPLY, ConfigData: response.config.ConfigData, }, @@ -555,6 +576,7 @@ func (n *Nginx) rollbackConfigApply(response *NginxConfigValidationResponse) { CorrelationId: response.correlationId, Status: proto.NginxConfigStatus_ERROR, Message: nginxConfigStatusMessage, + NginxId: response.config.GetConfigData().GetNginxId(), }, }, } @@ -616,16 +638,7 @@ func (n *Nginx) syncAgentConfigChange() { n.isNAPEnabled = false } - n.isConfUploadEnabled = isConfUploadEnabled(conf) + n.isFeatureNginxConfigEnabled = conf.IsFeatureEnabled(agent_config.FeatureNginxConfig) n.config = conf } - -func isConfUploadEnabled(conf *config.Config) bool { - for _, feature := range conf.Features { - if feature == agent_config.FeatureNginxConfig { - return true - } - } - return false -} diff --git a/src/plugins/nginx_test.go b/src/plugins/nginx_test.go index 209e38547..7c6ea144e 100644 --- a/src/plugins/nginx_test.go +++ b/src/plugins/nginx_test.go @@ -12,7 +12,7 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "os" "testing" "time" @@ -21,12 +21,11 @@ import ( "github.com/stretchr/testify/mock" "github.com/nginx/agent/sdk/v2" + agent_config "github.com/nginx/agent/sdk/v2/agent/config" "github.com/nginx/agent/sdk/v2/checksum" "github.com/nginx/agent/sdk/v2/grpc" "github.com/nginx/agent/sdk/v2/proto" sdk_zip "github.com/nginx/agent/sdk/v2/zip" - - agent_config "github.com/nginx/agent/sdk/v2/agent/config" "github.com/nginx/agent/v2/src/core" loadedConfig "github.com/nginx/agent/v2/src/core/config" tutils "github.com/nginx/agent/v2/test/utils" @@ -480,16 +479,16 @@ func TestNginxConfigApply(t *testing.T) { t.Run(fmt.Sprintf("%d", idx), func(tt *testing.T) { dir := t.TempDir() var auxPath string - tempConf, err := ioutil.TempFile(dir, "nginx.conf") + tempConf, err := os.CreateTemp(dir, "nginx.conf") assert.NoError(t, err) - err = ioutil.WriteFile(tempConf.Name(), fourth, 0644) + err = os.WriteFile(tempConf.Name(), fourth, 0644) assert.NoError(t, err) if (test.config.GetZaux() != &proto.ZippedFile{} && len(test.config.GetZaux().GetContents()) > 0) { auxDir := t.TempDir() auxMainFile := fmt.Sprintf("%s/app_protect_metadata.json", auxDir) - err := ioutil.WriteFile(auxMainFile, wafMetaData1, 0644) + err := os.WriteFile(auxMainFile, wafMetaData1, 0644) assert.NoError(t, err) auxPath = auxMainFile @@ -529,8 +528,9 @@ func TestNginxConfigApply(t *testing.T) { binary.On("Reload", mock.Anything, mock.Anything).Return(nil) commandClient := tutils.GetMockCommandClient(test.config) + conf := &loadedConfig.Config{Server: loadedConfig.Server{Host: "127.0.0.1", GrpcPort: 9092}, Features: []string{agent_config.FeatureNginxConfig}} - pluginUnderTest := NewNginx(commandClient, binary, env, &loadedConfig.Config{Features: []string{agent_config.FeatureNginxConfig}}) + pluginUnderTest := NewNginx(commandClient, binary, env, conf) if (test.config.GetZaux() != &proto.ZippedFile{} && len(test.config.GetZaux().GetContents()) > 0) { pluginUnderTest.wafLocation = auxPath pluginUnderTest.wafVersion = test.wafVersion @@ -603,7 +603,9 @@ func TestUploadConfigs(t *testing.T) { cmdr := tutils.NewMockCommandClient() cmdr.On("Upload", mock.Anything, mock.Anything).Return(nil) - pluginUnderTest := NewNginx(cmdr, binary, env, &loadedConfig.Config{Features: []string{agent_config.FeatureNginxConfig}}) + conf := &loadedConfig.Config{Server: loadedConfig.Server{Host: "127.0.0.1", GrpcPort: 9092}, Features: []string{agent_config.FeatureNginxConfig}} + + pluginUnderTest := NewNginx(cmdr, binary, env, conf) messagePipe := core.SetupMockMessagePipe(t, context.Background(), pluginUnderTest) pluginUnderTest.Init(messagePipe) @@ -706,8 +708,9 @@ func TestNginx_Process_NginxConfigUpload(t *testing.T) { binary.On("ReadConfig", "/var/conf", "12345", "12345678").Return(config, nil) env := tutils.GetMockEnvWithProcess() + conf := &loadedConfig.Config{Server: loadedConfig.Server{Host: "127.0.0.1", GrpcPort: 9092}, Features: []string{agent_config.FeatureNginxConfig}} - pluginUnderTest := NewNginx(cmdr, binary, env, &loadedConfig.Config{Features: []string{agent_config.FeatureNginxConfig}}) + pluginUnderTest := NewNginx(cmdr, binary, env, conf) pluginUnderTest.Process(core.NewMessage(core.NginxConfigUpload, configDesc)) binary.AssertExpectations(t) @@ -769,8 +772,9 @@ func TestNginx_validateConfig(t *testing.T) { binary.On("ReadConfig", mock.Anything, mock.Anything, mock.Anything).Return(&proto.NginxConfig{}, nil) binary.On("GetNginxDetailsMapFromProcesses", env.Processes()).Return((tutils.GetDetailsMap())) binary.On("UpdateNginxDetailsFromProcesses", env.Processes()) + conf := &loadedConfig.Config{Server: loadedConfig.Server{Host: "127.0.0.1", GrpcPort: 9092}, Features: []string{agent_config.FeatureNginxConfig}} - pluginUnderTest := NewNginx(&tutils.MockCommandClient{}, binary, env, &loadedConfig.Config{Features: []string{agent_config.FeatureNginxConfig}}) + pluginUnderTest := NewNginx(&tutils.MockCommandClient{}, binary, env, conf) messagePipe := core.SetupMockMessagePipe(t, context.TODO(), pluginUnderTest) messagePipe.Run() @@ -838,10 +842,12 @@ func TestNginx_completeConfigApply(t *testing.T) { }, ) - pluginUnderTest := NewNginx(commandClient, binary, env, &loadedConfig.Config{Features: []string{agent_config.FeatureNginxConfig}}) + conf := &loadedConfig.Config{Server: loadedConfig.Server{Host: "127.0.0.1", GrpcPort: 9092}, Features: []string{agent_config.FeatureNginxConfig}} + + pluginUnderTest := NewNginx(commandClient, binary, env, conf) dir := t.TempDir() - tempConf, err := ioutil.TempFile(dir, "nginx.conf") + tempConf, err := os.CreateTemp(dir, "nginx.conf") assert.NoError(t, err) allowedDirectoriesMap := map[string]struct{}{dir: {}} configApply, err := sdk.NewConfigApply(tempConf.Name(), allowedDirectoriesMap) @@ -925,10 +931,12 @@ func TestNginx_rollbackConfigApply(t *testing.T) { }, ) - pluginUnderTest := NewNginx(commandClient, binary, env, &loadedConfig.Config{Features: []string{agent_config.FeatureNginxConfig}}) + conf := &loadedConfig.Config{Server: loadedConfig.Server{Host: "127.0.0.1", GrpcPort: 9092}, Features: []string{agent_config.FeatureNginxConfig}} + + pluginUnderTest := NewNginx(commandClient, binary, env, conf) dir := t.TempDir() - tempConf, err := ioutil.TempFile(dir, "nginx.conf") + tempConf, err := os.CreateTemp(dir, "nginx.conf") assert.NoError(t, err) allowedDirectoriesMap := map[string]struct{}{dir: {}} configApply, err := sdk.NewConfigApply(tempConf.Name(), allowedDirectoriesMap) diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/command.pb.go b/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/command.pb.go index 9cd0046a2..1eb5da172 100644 --- a/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/command.pb.go +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/command.pb.go @@ -631,6 +631,7 @@ type NginxConfigStatus struct { CorrelationId string `protobuf:"bytes,1,opt,name=correlation_id,json=correlationId,proto3" json:"correlation_id"` Status NginxConfigStatus_Status `protobuf:"varint,2,opt,name=status,proto3,enum=f5.nginx.agent.sdk.NginxConfigStatus_Status" json:"status"` Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message"` + NginxId string `protobuf:"bytes,4,opt,name=nginx_id,json=nginxId,proto3" json:"nginx_id"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -690,6 +691,13 @@ func (m *NginxConfigStatus) GetMessage() string { return "" } +func (m *NginxConfigStatus) GetNginxId() string { + if m != nil { + return m.NginxId + } + return "" +} + type DataplaneSoftwareHealth struct { // Types that are valid to be assigned to Health: // *DataplaneSoftwareHealth_NginxHealth @@ -1253,103 +1261,103 @@ func init() { func init() { proto.RegisterFile("command.proto", fileDescriptor_213c0bb044472049) } var fileDescriptor_213c0bb044472049 = []byte{ - // 1521 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x4d, 0x6f, 0xdb, 0xc6, - 0x16, 0x25, 0x15, 0xeb, 0xeb, 0x4a, 0xb6, 0x95, 0xb1, 0x93, 0x28, 0x46, 0x60, 0x1a, 0x7c, 0x2f, - 0x2f, 0xce, 0x7b, 0x79, 0x12, 0xea, 0xa0, 0x08, 0x9a, 0xac, 0x24, 0x4b, 0x09, 0x85, 0xc4, 0x92, - 0x31, 0x89, 0x13, 0x20, 0x45, 0x21, 0x30, 0xe2, 0x48, 0x16, 0x6c, 0x91, 0x2c, 0x49, 0x39, 0x71, - 0xd0, 0x7d, 0xd1, 0xa2, 0x9b, 0x2e, 0xba, 0x28, 0xfa, 0x23, 0xfa, 0x37, 0xba, 0xcc, 0xba, 0x0b, - 0xa2, 0xc8, 0x92, 0xbb, 0x6e, 0xda, 0x45, 0x37, 0xc5, 0x7c, 0x50, 0xa2, 0x24, 0x4a, 0x76, 0xea, - 0xa2, 0x1b, 0xce, 0x70, 0x78, 0xee, 0xb9, 0x77, 0xee, 0xcc, 0x9c, 0xb9, 0x12, 0x2c, 0x77, 0xac, - 0xc1, 0x40, 0x37, 0x8d, 0x92, 0xed, 0x58, 0x9e, 0x85, 0x50, 0xf7, 0xe3, 0x92, 0xd9, 0xeb, 0x9b, - 0x6f, 0x4a, 0x7a, 0x8f, 0x98, 0x5e, 0xc9, 0x35, 0x8e, 0x36, 0xa0, 0x67, 0xf5, 0x2c, 0xfe, 0x7d, - 0x23, 0x4f, 0xe1, 0x96, 0x29, 0xde, 0x72, 0x1c, 0xc4, 0x5f, 0xe0, 0xd0, 0x72, 0xc3, 0x7e, 0x8e, - 0x73, 0x8c, 0x6c, 0xcc, 0x6e, 0xbf, 0x27, 0xde, 0x10, 0x39, 0x21, 0xa6, 0xe7, 0x96, 0x59, 0x23, - 0xc6, 0xae, 0x1b, 0x76, 0xdb, 0xb5, 0xba, 0xde, 0x6b, 0xdd, 0x21, 0x6d, 0x83, 0x78, 0x7a, 0xff, - 0xd8, 0x15, 0x9f, 0xb2, 0xa6, 0x6e, 0xf3, 0xae, 0xfa, 0x07, 0x40, 0x7a, 0x97, 0x47, 0x8b, 0xee, - 0xc3, 0xd2, 0x80, 0x78, 0x7a, 0x51, 0xde, 0x92, 0xb7, 0x73, 0x3b, 0x37, 0x4a, 0xb3, 0x61, 0x97, - 0xf6, 0x88, 0xa7, 0x1b, 0xba, 0xa7, 0x57, 0x33, 0x81, 0xaf, 0x30, 0x34, 0x66, 0x4f, 0x54, 0x87, - 0x25, 0xef, 0xd4, 0x26, 0xc5, 0xc4, 0x96, 0xbc, 0xbd, 0xb2, 0x73, 0x2b, 0xce, 0x56, 0xb8, 0x09, - 0xdb, 0x67, 0xa7, 0x36, 0xe1, 0x34, 0xd4, 0x10, 0xb3, 0x27, 0x7a, 0x09, 0xd0, 0x19, 0x18, 0x6d, - 0xd7, 0xd3, 0xbd, 0xa1, 0x5b, 0xbc, 0xc4, 0x02, 0xb9, 0xbd, 0x80, 0xec, 0x29, 0x03, 0x62, 0xe2, - 0xda, 0x96, 0xe9, 0x92, 0xea, 0x4a, 0xe0, 0x2b, 0x11, 0x02, 0x4d, 0xc2, 0xd9, 0xce, 0x40, 0x80, - 0xd0, 0x73, 0xc8, 0x33, 0x96, 0x36, 0x4f, 0x5d, 0x71, 0x89, 0xb1, 0x2b, 0x71, 0xec, 0x4d, 0xfa, - 0xbe, 0xcb, 0x60, 0xd5, 0x42, 0xe0, 0x2b, 0x13, 0x86, 0x9a, 0x84, 0xf9, 0x52, 0x70, 0x00, 0x7a, - 0x03, 0x57, 0xa2, 0x9f, 0xdb, 0x8e, 0x88, 0xa6, 0x98, 0x64, 0x0e, 0x6e, 0x9d, 0xe1, 0x60, 0x14, - 0xfc, 0xf5, 0xc0, 0x57, 0xe2, 0x99, 0x34, 0x09, 0xaf, 0x99, 0xb3, 0x16, 0xd4, 0x33, 0xa3, 0xa4, - 0x78, 0x93, 0x74, 0xbc, 0xb6, 0x43, 0x3e, 0x1f, 0x12, 0xd7, 0x2b, 0xa6, 0xe6, 0x7b, 0xae, 0xd0, - 0xde, 0x2e, 0xc7, 0x63, 0x0e, 0xe7, 0x9e, 0x63, 0x99, 0xa8, 0x67, 0x7d, 0xd6, 0x02, 0x7d, 0x01, - 0x57, 0xa7, 0xf1, 0x62, 0xd2, 0x69, 0xe6, 0x7a, 0xfb, 0x6c, 0xd7, 0x62, 0xd6, 0x1b, 0x81, 0xaf, - 0xcc, 0xe1, 0xd2, 0x24, 0xbc, 0xae, 0xc7, 0xd8, 0x20, 0x0f, 0xd6, 0x47, 0x16, 0x3c, 0x4f, 0x7c, - 0xda, 0x19, 0xe6, 0xfb, 0x3f, 0x8b, 0x7c, 0xb3, 0xf4, 0xf1, 0x59, 0x17, 0x03, 0x5f, 0x89, 0xe5, - 0xd1, 0x24, 0x8c, 0xf4, 0x19, 0x3c, 0xdd, 0x3f, 0x51, 0x74, 0x31, 0x3b, 0x7f, 0xff, 0x44, 0xbc, - 0xf1, 0xfd, 0x13, 0x35, 0xa4, 0xfb, 0x27, 0x42, 0x8f, 0xba, 0x50, 0xa0, 0x47, 0xca, 0x3e, 0xd6, - 0x4d, 0x12, 0xee, 0xfc, 0x1c, 0xe3, 0xfe, 0x57, 0x1c, 0x77, 0x2d, 0xc4, 0xf2, 0x6d, 0x5d, 0x5d, - 0x0f, 0x7c, 0x65, 0x86, 0x40, 0x93, 0xf0, 0xaa, 0x31, 0x09, 0x44, 0x9f, 0x41, 0x9e, 0xe9, 0x43, - 0xdb, 0x21, 0xb6, 0xe5, 0x78, 0xc5, 0xfc, 0xfc, 0x6c, 0x71, 0x39, 0x29, 0xd5, 0x69, 0x83, 0x19, - 0x9a, 0x4f, 0x23, 0x6a, 0x4f, 0xa7, 0x41, 0xc6, 0x00, 0xf4, 0x8d, 0x0c, 0x1b, 0x91, 0x30, 0xa6, - 0x94, 0xa7, 0xb8, 0xcc, 0xbc, 0xdd, 0x59, 0x3c, 0x23, 0x61, 0x54, 0xe3, 0x36, 0xd5, 0xcd, 0xc0, - 0x57, 0x16, 0x70, 0x6a, 0x12, 0x2e, 0x1a, 0x73, 0x6c, 0x27, 0xb3, 0x3a, 0xb4, 0x0d, 0xdd, 0x23, - 0xc5, 0x95, 0x73, 0x64, 0xf5, 0x80, 0x41, 0xa7, 0xb3, 0xca, 0x09, 0x26, 0xb2, 0xca, 0x81, 0xea, - 0x5d, 0xc8, 0x45, 0x04, 0x0d, 0x01, 0xa4, 0x9a, 0x2d, 0xbc, 0x57, 0x79, 0x52, 0x90, 0x50, 0x1e, - 0x32, 0xb5, 0xd6, 0x8b, 0xe6, 0x93, 0x56, 0xa5, 0x56, 0x90, 0xe9, 0x97, 0x83, 0x7d, 0xd6, 0x4f, - 0x54, 0x53, 0xb0, 0x44, 0x79, 0xd4, 0xef, 0x2e, 0xc1, 0x95, 0x58, 0x25, 0x43, 0x9f, 0x42, 0x4a, - 0x6c, 0x05, 0x99, 0x29, 0xea, 0xbd, 0x73, 0x8b, 0xe0, 0xe4, 0x68, 0x15, 0x02, 0x5f, 0x11, 0x54, - 0x58, 0xb4, 0xa8, 0x0f, 0x40, 0x1c, 0xc7, 0x72, 0xda, 0x1d, 0xcb, 0x08, 0x25, 0xfb, 0xfe, 0x07, - 0x3b, 0xa8, 0x53, 0x8a, 0x5d, 0xcb, 0x10, 0xb2, 0x3b, 0x66, 0xc4, 0x59, 0x12, 0x7e, 0x42, 0x37, - 0x21, 0x3d, 0x20, 0xae, 0xab, 0xf7, 0x08, 0x53, 0xf3, 0x6c, 0x35, 0x17, 0xf8, 0x4a, 0x38, 0x84, - 0xc3, 0x0e, 0x52, 0x20, 0xc9, 0x6c, 0x98, 0x28, 0x67, 0xab, 0xd9, 0xc0, 0x57, 0xf8, 0x00, 0xe6, - 0x8d, 0xfa, 0x00, 0x96, 0x27, 0x82, 0x41, 0xab, 0x90, 0xdb, 0xdd, 0xab, 0xb5, 0x0f, 0x9a, 0x8f, - 0x9b, 0xad, 0x17, 0xcd, 0x82, 0x44, 0xf3, 0x4b, 0x07, 0x5a, 0x8f, 0x0b, 0x32, 0x5a, 0x86, 0x2c, - 0xed, 0xd7, 0x31, 0x6e, 0xe1, 0x42, 0x42, 0x2d, 0x43, 0x61, 0x3a, 0x66, 0x0a, 0xaf, 0x63, 0x4c, - 0xe1, 0x12, 0xe5, 0xa2, 0xfd, 0x90, 0x4b, 0x56, 0x7f, 0x48, 0xc2, 0xea, 0xd4, 0x39, 0x43, 0xff, - 0x85, 0xac, 0x7b, 0xea, 0x7a, 0x64, 0xd0, 0xee, 0x1b, 0x6c, 0x51, 0xb2, 0xd5, 0xe5, 0xc0, 0x57, - 0xc6, 0x83, 0x38, 0xc3, 0xbb, 0x0d, 0x03, 0x3d, 0x82, 0x74, 0xb8, 0xef, 0x13, 0x5b, 0x97, 0xb6, - 0x73, 0x3b, 0x5b, 0x73, 0x2f, 0x81, 0x70, 0xaf, 0xb3, 0xbc, 0x08, 0x23, 0x1c, 0x76, 0xe8, 0x95, - 0x4c, 0x2b, 0x00, 0x71, 0x13, 0xc6, 0x5e, 0xc9, 0x9a, 0xe5, 0x7a, 0x0d, 0xb3, 0x6b, 0xf1, 0xbb, - 0x94, 0xa2, 0x31, 0x7b, 0xa2, 0x87, 0x90, 0x3e, 0x24, 0xfa, 0xb1, 0x77, 0xe8, 0x16, 0x93, 0x2c, - 0x88, 0xf9, 0x57, 0x9d, 0xc6, 0x70, 0x3c, 0x06, 0x61, 0x83, 0xc3, 0x0e, 0xfa, 0x7a, 0xf1, 0xc1, - 0x4e, 0x31, 0xee, 0xbf, 0xf5, 0x60, 0x2f, 0x38, 0xd6, 0x5f, 0xc5, 0x07, 0x13, 0x4e, 0x34, 0xcd, - 0x82, 0xf9, 0xdf, 0xb9, 0x82, 0x11, 0x93, 0x9e, 0x17, 0x4b, 0x98, 0x87, 0xd9, 0x58, 0x34, 0x91, - 0x98, 0x93, 0xf0, 0xfa, 0xd5, 0x3b, 0x5e, 0xff, 0xa4, 0xef, 0x9d, 0x86, 0xea, 0x9d, 0x61, 0x51, - 0xcc, 0xbf, 0x7e, 0x2b, 0x02, 0x2f, 0x8e, 0x68, 0xe4, 0xfa, 0x9d, 0x62, 0x12, 0x97, 0xef, 0x24, - 0x5e, 0xfd, 0x56, 0x86, 0xb5, 0x18, 0x1e, 0x64, 0xc3, 0xda, 0x44, 0xf9, 0x10, 0x11, 0x90, 0xdc, - 0xce, 0xcd, 0x33, 0xca, 0x10, 0x11, 0xcb, 0xb5, 0xc0, 0x57, 0xe2, 0x58, 0x34, 0x09, 0x5f, 0x36, - 0x67, 0xd0, 0x19, 0x48, 0x89, 0x98, 0x7e, 0x95, 0xe1, 0xf2, 0x0c, 0x1b, 0xfa, 0x04, 0x56, 0x3a, - 0x96, 0xe3, 0x90, 0x63, 0xdd, 0xeb, 0x5b, 0xe6, 0xf8, 0xe0, 0xa0, 0xc0, 0x57, 0xa6, 0xbe, 0xe0, - 0xe5, 0xc8, 0x7b, 0xc3, 0x40, 0xfb, 0x23, 0x01, 0xe4, 0xfa, 0x74, 0xe7, 0x5c, 0xf1, 0x97, 0x16, - 0xa8, 0xde, 0xf9, 0xa4, 0x48, 0xdd, 0x0e, 0xe7, 0x84, 0x72, 0x90, 0xde, 0xaf, 0x37, 0x6b, 0x8d, - 0xe6, 0xa3, 0x82, 0x84, 0x52, 0x90, 0x60, 0xd2, 0x92, 0x85, 0x64, 0x28, 0x2b, 0xbf, 0xcb, 0x70, - 0x6d, 0xce, 0xae, 0x1a, 0x17, 0x9b, 0x7c, 0x1b, 0x89, 0x45, 0x38, 0xf3, 0x04, 0x46, 0x8a, 0x4d, - 0x6e, 0x38, 0x2a, 0x36, 0x05, 0xef, 0x5b, 0xb8, 0xaa, 0xdb, 0x76, 0x9b, 0x16, 0xef, 0xb4, 0x54, - 0x7a, 0xad, 0x77, 0x43, 0x0f, 0x89, 0x05, 0x35, 0x9f, 0x6d, 0xef, 0x73, 0x83, 0x17, 0x95, 0x87, - 0xc2, 0x13, 0xaf, 0xbb, 0x62, 0xa9, 0x58, 0xd1, 0x37, 0x36, 0xd1, 0xbb, 0xc2, 0x24, 0x03, 0x29, - 0x0e, 0x50, 0x7f, 0x96, 0x23, 0xfa, 0xc8, 0x2f, 0xc2, 0x91, 0x54, 0xc9, 0x7f, 0x41, 0xaa, 0xce, - 0x90, 0x98, 0xc4, 0x3f, 0x29, 0x31, 0xea, 0x1e, 0xac, 0xd6, 0xac, 0xd7, 0xe6, 0xb1, 0xa5, 0x1b, - 0x61, 0xe9, 0x77, 0x81, 0x5f, 0x46, 0xea, 0x97, 0x09, 0x58, 0x8b, 0x29, 0xf7, 0xd1, 0xde, 0xc4, - 0x0d, 0xff, 0x41, 0x3f, 0x73, 0xe2, 0x76, 0x77, 0x03, 0x52, 0x54, 0x3c, 0x2c, 0x53, 0x9c, 0x97, - 0xb3, 0xce, 0x7b, 0x85, 0x81, 0x39, 0x15, 0x37, 0xc4, 0xa2, 0x45, 0xcf, 0x21, 0x27, 0xce, 0x3e, - 0x9d, 0x90, 0xb8, 0x7b, 0xfe, 0x1d, 0x1f, 0x1e, 0x85, 0xd5, 0x88, 0xdb, 0x71, 0xfa, 0xb6, 0x67, - 0x39, 0xd5, 0xd5, 0xc0, 0x57, 0xa2, 0xc6, 0x18, 0xf8, 0x0b, 0x5d, 0x26, 0xf5, 0x37, 0x19, 0xf2, - 0x07, 0x36, 0xcd, 0xab, 0x38, 0x60, 0x17, 0xf9, 0xc1, 0xf9, 0x74, 0x4a, 0x1f, 0xca, 0x71, 0xd6, - 0x51, 0x6f, 0xa5, 0x67, 0x8e, 0x6e, 0xba, 0x5d, 0xe2, 0x2c, 0x90, 0x08, 0x15, 0x52, 0x0e, 0xd1, - 0x5d, 0xcb, 0x14, 0x0a, 0xc1, 0x30, 0x7c, 0x04, 0x8b, 0x56, 0xfd, 0x08, 0x56, 0x26, 0x99, 0xa8, - 0x4e, 0x8c, 0xcb, 0x90, 0x50, 0x27, 0x00, 0x52, 0x0f, 0x2b, 0x8d, 0x27, 0xf5, 0x5a, 0x21, 0xa1, - 0xfe, 0x28, 0x43, 0x96, 0x66, 0x60, 0xf7, 0x70, 0x68, 0x1e, 0xa1, 0x16, 0x3b, 0x46, 0x06, 0x71, - 0x16, 0x2e, 0x3c, 0x85, 0x12, 0x03, 0x13, 0xd7, 0x1a, 0x3a, 0x1d, 0xaa, 0x2a, 0x06, 0x71, 0x78, - 0x3c, 0xdc, 0x58, 0x93, 0xb0, 0xe8, 0x21, 0x8d, 0x57, 0x93, 0x42, 0x01, 0xb6, 0xcf, 0x41, 0xc7, - 0x5e, 0x79, 0x4a, 0xa9, 0xa5, 0x26, 0x61, 0xd6, 0x56, 0xd3, 0x90, 0xec, 0xd0, 0x4f, 0xea, 0x3b, - 0x19, 0xae, 0xc4, 0x86, 0x70, 0xa1, 0x35, 0x53, 0x21, 0xc5, 0xe8, 0xf9, 0x9a, 0x25, 0xf9, 0x74, - 0xf8, 0x08, 0x16, 0x2d, 0xda, 0x86, 0x4c, 0xe7, 0x90, 0x74, 0x8e, 0xdc, 0xe1, 0x40, 0x2c, 0x42, - 0x3e, 0xf0, 0x95, 0xd1, 0x18, 0x1e, 0xf5, 0xd0, 0xff, 0x01, 0x98, 0x4d, 0xdb, 0xed, 0xbf, 0x25, - 0xac, 0x70, 0x4c, 0x8a, 0x3f, 0x00, 0x46, 0xa3, 0x38, 0xcb, 0xfa, 0x4f, 0xfb, 0x6f, 0x89, 0xfa, - 0xbd, 0x0c, 0xeb, 0x71, 0x69, 0xb8, 0xd0, 0x8c, 0x6e, 0xd1, 0x68, 0xa9, 0xb7, 0xbe, 0x21, 0xe6, - 0x24, 0xa2, 0xe5, 0x63, 0x38, 0xcd, 0x7a, 0x0d, 0x03, 0xdd, 0x10, 0x6b, 0x44, 0xa7, 0x94, 0x1f, - 0x67, 0x5e, 0xe4, 0xfd, 0xde, 0x4f, 0xef, 0x37, 0xe5, 0x77, 0xef, 0x37, 0xe5, 0x5f, 0xde, 0x6f, - 0xca, 0x2f, 0x6f, 0xf7, 0xfa, 0xde, 0xe1, 0xf0, 0x55, 0xa9, 0x63, 0x0d, 0xca, 0x2c, 0x92, 0x32, - 0x8b, 0xa4, 0xec, 0x1a, 0x47, 0xe5, 0x93, 0x9d, 0x32, 0xfb, 0xe3, 0xe6, 0x01, 0x7b, 0xbe, 0x4a, - 0xb1, 0xe6, 0xee, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc3, 0xee, 0xd6, 0x35, 0x72, 0x12, 0x00, - 0x00, + // 1535 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xcb, 0x6e, 0xdb, 0x46, + 0x17, 0x26, 0x15, 0xeb, 0x76, 0x24, 0xdb, 0xca, 0xd8, 0x49, 0x14, 0x23, 0x30, 0x0d, 0xfe, 0x7f, + 0x6a, 0xa7, 0x4d, 0x25, 0xd4, 0x41, 0x11, 0x34, 0x59, 0x59, 0x96, 0x13, 0x0a, 0x89, 0x65, 0x63, + 0x12, 0x27, 0x40, 0x8a, 0x42, 0x60, 0xc4, 0x91, 0x4c, 0xd8, 0x22, 0x59, 0x92, 0x72, 0xe2, 0xa0, + 0xfb, 0xa2, 0x45, 0x37, 0x5d, 0x74, 0xd1, 0xf6, 0x21, 0xfa, 0x1a, 0x5d, 0x66, 0xdd, 0x05, 0x51, + 0x64, 0xc9, 0x07, 0x68, 0x17, 0xdd, 0x14, 0x73, 0xa1, 0x44, 0x49, 0x94, 0xec, 0xd4, 0x45, 0x37, + 0x9a, 0xe1, 0xf0, 0x3b, 0xdf, 0xb9, 0xcc, 0xcc, 0x37, 0x43, 0xc1, 0x7c, 0xdb, 0xee, 0xf5, 0x74, + 0xcb, 0xa8, 0x38, 0xae, 0xed, 0xdb, 0x08, 0x75, 0x3e, 0xad, 0x58, 0x5d, 0xd3, 0x7a, 0x5d, 0xd1, + 0xbb, 0xc4, 0xf2, 0x2b, 0x9e, 0x71, 0xb4, 0x02, 0x5d, 0xbb, 0x6b, 0xf3, 0xf7, 0x2b, 0x45, 0x0a, + 0xb7, 0x2d, 0xf1, 0x54, 0xe0, 0x20, 0xfe, 0x00, 0x87, 0xb6, 0x17, 0xf5, 0x0b, 0x9c, 0x63, 0x60, + 0x63, 0x75, 0xcc, 0xae, 0x78, 0x42, 0xe4, 0x84, 0x58, 0xbe, 0x57, 0x65, 0x8d, 0x18, 0xbb, 0x6e, + 0x38, 0x2d, 0xcf, 0xee, 0xf8, 0xaf, 0x74, 0x97, 0xb4, 0x0c, 0xe2, 0xeb, 0xe6, 0xb1, 0x27, 0x5e, + 0xe5, 0x2d, 0xdd, 0xe1, 0x5d, 0xf5, 0x2f, 0x80, 0xec, 0x36, 0x8f, 0x16, 0xdd, 0x83, 0xb9, 0x1e, + 0xf1, 0xf5, 0xb2, 0xbc, 0x26, 0x6f, 0x14, 0x36, 0x6f, 0x54, 0x26, 0xc3, 0xae, 0xec, 0x12, 0x5f, + 0x37, 0x74, 0x5f, 0xaf, 0xe5, 0xc2, 0x40, 0x61, 0x68, 0xcc, 0x7e, 0xd1, 0x0e, 0xcc, 0xf9, 0xa7, + 0x0e, 0x29, 0xa7, 0xd6, 0xe4, 0x8d, 0x85, 0xcd, 0xf5, 0x24, 0x5b, 0xe1, 0x26, 0x6a, 0x9f, 0x9e, + 0x3a, 0x84, 0xd3, 0x50, 0x43, 0xcc, 0x7e, 0xd1, 0x0b, 0x80, 0x76, 0xcf, 0x68, 0x79, 0xbe, 0xee, + 0xf7, 0xbd, 0xf2, 0x25, 0x16, 0xc8, 0xad, 0x19, 0x64, 0x4f, 0x18, 0x10, 0x13, 0xcf, 0xb1, 0x2d, + 0x8f, 0xd4, 0x16, 0xc2, 0x40, 0x89, 0x11, 0x68, 0x12, 0xce, 0xb7, 0x7b, 0x02, 0x84, 0x9e, 0x41, + 0x91, 0xb1, 0xb4, 0x78, 0xe9, 0xca, 0x73, 0x8c, 0x5d, 0x49, 0x62, 0x6f, 0xd2, 0xe7, 0x6d, 0x06, + 0xab, 0x95, 0xc2, 0x40, 0x19, 0x31, 0xd4, 0x24, 0xcc, 0xa7, 0x82, 0x03, 0xd0, 0x6b, 0xb8, 0x12, + 0x7f, 0xdd, 0x72, 0x45, 0x34, 0xe5, 0x34, 0x73, 0xb0, 0x7e, 0x86, 0x83, 0x41, 0xf0, 0xd7, 0xc3, + 0x40, 0x49, 0x66, 0xd2, 0x24, 0xbc, 0x64, 0x4d, 0x5a, 0x50, 0xcf, 0x8c, 0x92, 0xe2, 0x2d, 0xd2, + 0xf6, 0x5b, 0x2e, 0xf9, 0xb2, 0x4f, 0x3c, 0xbf, 0x9c, 0x99, 0xee, 0x79, 0x8b, 0xf6, 0xb6, 0x39, + 0x1e, 0x73, 0x38, 0xf7, 0x9c, 0xc8, 0x44, 0x3d, 0xeb, 0x93, 0x16, 0xe8, 0x2b, 0xb8, 0x3a, 0x8e, + 0x17, 0x49, 0x67, 0x99, 0xeb, 0x8d, 0xb3, 0x5d, 0x8b, 0xac, 0x57, 0xc2, 0x40, 0x99, 0xc2, 0xa5, + 0x49, 0x78, 0x59, 0x4f, 0xb0, 0x41, 0x3e, 0x2c, 0x0f, 0x2c, 0x78, 0x9d, 0x78, 0xda, 0x39, 0xe6, + 0xfb, 0x83, 0x59, 0xbe, 0x59, 0xf9, 0x78, 0xd6, 0xe5, 0x30, 0x50, 0x12, 0x79, 0x34, 0x09, 0x23, + 0x7d, 0x02, 0x4f, 0xd7, 0x4f, 0x1c, 0x5d, 0xce, 0x4f, 0x5f, 0x3f, 0x31, 0x6f, 0x7c, 0xfd, 0xc4, + 0x0d, 0xe9, 0xfa, 0x89, 0xd1, 0xa3, 0x0e, 0x94, 0xe8, 0x96, 0x72, 0x8e, 0x75, 0x8b, 0x44, 0x2b, + 0xbf, 0xc0, 0xb8, 0xff, 0x97, 0xc4, 0x5d, 0x8f, 0xb0, 0x7c, 0x59, 0xd7, 0x96, 0xc3, 0x40, 0x99, + 0x20, 0xd0, 0x24, 0xbc, 0x68, 0x8c, 0x02, 0xd1, 0x17, 0x50, 0x64, 0xfa, 0xd0, 0x72, 0x89, 0x63, + 0xbb, 0x7e, 0xb9, 0x38, 0xbd, 0x5a, 0x5c, 0x4e, 0x2a, 0x3b, 0xb4, 0xc1, 0x0c, 0xcd, 0xd3, 0x88, + 0xdb, 0xd3, 0x34, 0xc8, 0x10, 0x80, 0xbe, 0x93, 0x61, 0x25, 0x16, 0xc6, 0x98, 0xf2, 0x94, 0xe7, + 0x99, 0xb7, 0xdb, 0xb3, 0x33, 0x12, 0x46, 0x75, 0x6e, 0x53, 0x5b, 0x0d, 0x03, 0x65, 0x06, 0xa7, + 0x26, 0xe1, 0xb2, 0x31, 0xc5, 0x76, 0xb4, 0xaa, 0x7d, 0xc7, 0xd0, 0x7d, 0x52, 0x5e, 0x38, 0x47, + 0x55, 0x0f, 0x18, 0x74, 0xbc, 0xaa, 0x9c, 0x60, 0xa4, 0xaa, 0x1c, 0xa8, 0xde, 0x81, 0x42, 0x4c, + 0xd0, 0x10, 0x40, 0xa6, 0xb9, 0x87, 0x77, 0xb7, 0x1e, 0x97, 0x24, 0x54, 0x84, 0x5c, 0x7d, 0xef, + 0x79, 0xf3, 0xf1, 0xde, 0x56, 0xbd, 0x24, 0xd3, 0x37, 0x07, 0xfb, 0xac, 0x9f, 0xaa, 0x65, 0x60, + 0x8e, 0xf2, 0xa8, 0x3f, 0x5c, 0x82, 0x2b, 0x89, 0x4a, 0x86, 0x3e, 0x87, 0x8c, 0x58, 0x0a, 0x32, + 0x53, 0xd4, 0xbb, 0xe7, 0x16, 0xc1, 0xd1, 0xd1, 0x1a, 0x84, 0x81, 0x22, 0xa8, 0xb0, 0x68, 0x91, + 0x09, 0x40, 0x5c, 0xd7, 0x76, 0x5b, 0x6d, 0xdb, 0x88, 0x24, 0xfb, 0xde, 0x7b, 0x3b, 0xd8, 0xa1, + 0x14, 0xdb, 0xb6, 0x21, 0x64, 0x77, 0xc8, 0x88, 0xf3, 0x24, 0x7a, 0x85, 0x6e, 0x42, 0xb6, 0x47, + 0x3c, 0x4f, 0xef, 0x12, 0xa6, 0xe6, 0xf9, 0x5a, 0x21, 0x0c, 0x94, 0x68, 0x08, 0x47, 0x1d, 0xa4, + 0x40, 0x9a, 0xd9, 0x30, 0x51, 0xce, 0xd7, 0xf2, 0x61, 0xa0, 0xf0, 0x01, 0xcc, 0x1b, 0xf5, 0x3e, + 0xcc, 0x8f, 0x04, 0x83, 0x16, 0xa1, 0xb0, 0xbd, 0x5b, 0x6f, 0x1d, 0x34, 0x1f, 0x35, 0xf7, 0x9e, + 0x37, 0x4b, 0x12, 0xad, 0x2f, 0x1d, 0xd8, 0x7b, 0x54, 0x92, 0xd1, 0x3c, 0xe4, 0x69, 0x7f, 0x07, + 0xe3, 0x3d, 0x5c, 0x4a, 0xa9, 0x55, 0x28, 0x8d, 0xc7, 0x4c, 0xe1, 0x3b, 0x18, 0x53, 0xb8, 0x44, + 0xb9, 0x68, 0x3f, 0xe2, 0x92, 0xd5, 0x9f, 0xd3, 0xb0, 0x38, 0xb6, 0xcf, 0xd0, 0x87, 0x90, 0xf7, + 0x4e, 0x3d, 0x9f, 0xf4, 0x5a, 0xa6, 0xc1, 0x26, 0x25, 0x5f, 0x9b, 0x0f, 0x03, 0x65, 0x38, 0x88, + 0x73, 0xbc, 0xdb, 0x30, 0xd0, 0x43, 0xc8, 0x46, 0xeb, 0x3e, 0xb5, 0x76, 0x69, 0xa3, 0xb0, 0xb9, + 0x36, 0xf5, 0x10, 0x88, 0xd6, 0x3a, 0xab, 0x8b, 0x30, 0xc2, 0x51, 0x87, 0x1e, 0xc9, 0xf4, 0x06, + 0x20, 0x4e, 0xc2, 0xc4, 0x23, 0x59, 0xb3, 0x3d, 0xbf, 0x61, 0x75, 0x6c, 0x7e, 0x96, 0x52, 0x34, + 0x66, 0xbf, 0xe8, 0x01, 0x64, 0x0f, 0x89, 0x7e, 0xec, 0x1f, 0x7a, 0xe5, 0x34, 0x0b, 0x62, 0xfa, + 0x51, 0xa7, 0x31, 0x1c, 0x8f, 0x41, 0xd8, 0xe0, 0xa8, 0x83, 0xbe, 0x9d, 0xbd, 0xb1, 0x33, 0x8c, + 0xfb, 0x5f, 0xdd, 0xd8, 0x33, 0xb6, 0xf5, 0x37, 0xc9, 0xc1, 0x44, 0x89, 0x66, 0x59, 0x30, 0x1f, + 0x9d, 0x2b, 0x18, 0x91, 0xf4, 0xb4, 0x58, 0xa2, 0x3a, 0x4c, 0xc6, 0xa2, 0x89, 0xc2, 0x9c, 0x44, + 0xc7, 0xaf, 0xde, 0xf6, 0xcd, 0x13, 0xd3, 0x3f, 0x8d, 0xd4, 0x3b, 0xc7, 0xa2, 0x98, 0x7e, 0xfc, + 0x6e, 0x09, 0xbc, 0xd8, 0xa2, 0xb1, 0xe3, 0x77, 0x8c, 0x49, 0x1c, 0xbe, 0xa3, 0x78, 0xf5, 0x7b, + 0x19, 0x96, 0x12, 0x78, 0x90, 0x03, 0x4b, 0x23, 0xd7, 0x87, 0x98, 0x80, 0x14, 0x36, 0x6f, 0x9e, + 0x71, 0x0d, 0x11, 0xb1, 0x5c, 0x0b, 0x03, 0x25, 0x89, 0x45, 0x93, 0xf0, 0x65, 0x6b, 0x02, 0x9d, + 0x83, 0x8c, 0x88, 0xe9, 0xa7, 0x14, 0x5c, 0x9e, 0x60, 0x43, 0x9f, 0xc1, 0x42, 0xdb, 0x76, 0x5d, + 0x72, 0xac, 0xfb, 0xa6, 0x6d, 0x0d, 0x37, 0x0e, 0x0a, 0x03, 0x65, 0xec, 0x0d, 0x9e, 0x8f, 0x3d, + 0x37, 0x0c, 0xb4, 0x3f, 0x10, 0x40, 0xae, 0x4f, 0xb7, 0xcf, 0x15, 0x7f, 0x65, 0x86, 0xea, 0x9d, + 0x53, 0x8a, 0xd6, 0x21, 0xc7, 0xf3, 0x37, 0x0d, 0xa1, 0x46, 0xc5, 0x30, 0x50, 0x06, 0x63, 0x38, + 0xcb, 0x7a, 0x0d, 0x43, 0xdd, 0x88, 0x92, 0x47, 0x05, 0xc8, 0xee, 0xef, 0x34, 0xeb, 0x8d, 0xe6, + 0xc3, 0x92, 0x84, 0x32, 0x90, 0x62, 0x1a, 0x94, 0x87, 0x74, 0xa4, 0x3f, 0x7f, 0xca, 0x70, 0x6d, + 0xca, 0xf2, 0x1b, 0xde, 0x4a, 0xf9, 0x7a, 0x13, 0xb3, 0x75, 0xe6, 0x56, 0x8d, 0xdd, 0x4a, 0xb9, + 0xe1, 0xe0, 0x56, 0x2a, 0x78, 0xdf, 0xc0, 0x55, 0xdd, 0x71, 0x5a, 0xf4, 0x96, 0x4f, 0xef, 0x54, + 0xaf, 0xf4, 0x4e, 0xe4, 0x21, 0x35, 0xe3, 0x72, 0xe8, 0x38, 0xfb, 0xdc, 0xe0, 0xf9, 0xd6, 0x03, + 0xe1, 0x89, 0x5f, 0xd0, 0x12, 0xa9, 0xd8, 0xed, 0x70, 0x68, 0xa2, 0x77, 0x84, 0x49, 0x0e, 0x32, + 0x1c, 0xa0, 0xfe, 0x26, 0xc7, 0x84, 0x94, 0x9f, 0x98, 0x03, 0x4d, 0x93, 0xff, 0x81, 0xa6, 0x9d, + 0xa1, 0x45, 0xa9, 0xff, 0x52, 0x8b, 0xd4, 0x5d, 0x58, 0xac, 0xdb, 0xaf, 0xac, 0x63, 0x5b, 0x37, + 0xa2, 0x3b, 0xe2, 0x05, 0x3e, 0xa1, 0xd4, 0xaf, 0x53, 0xb0, 0x94, 0xf0, 0x5d, 0x80, 0x76, 0x47, + 0xae, 0x02, 0xef, 0xf5, 0x3d, 0x94, 0xb4, 0x0d, 0x1a, 0x90, 0xa1, 0x2a, 0x63, 0x5b, 0x62, 0x63, + 0x9d, 0x25, 0x0c, 0x5b, 0x0c, 0xcc, 0xa9, 0xb8, 0x21, 0x16, 0x2d, 0x7a, 0x06, 0x05, 0x21, 0x12, + 0x34, 0x21, 0x71, 0x48, 0xfd, 0x3f, 0x39, 0x3c, 0x0a, 0xab, 0x13, 0xaf, 0xed, 0x9a, 0x8e, 0x6f, + 0xbb, 0xb5, 0xc5, 0x30, 0x50, 0xe2, 0xc6, 0x18, 0xf8, 0x03, 0x9d, 0x26, 0xf5, 0x0f, 0x19, 0x8a, + 0x07, 0x0e, 0xad, 0xab, 0xd8, 0x60, 0x17, 0xf9, 0x32, 0x7d, 0x32, 0x26, 0x24, 0xd5, 0x24, 0xeb, + 0xb8, 0xb7, 0xca, 0x53, 0x57, 0xb7, 0xbc, 0x0e, 0x71, 0x67, 0x68, 0x89, 0x0a, 0x19, 0x97, 0xe8, + 0x9e, 0x6d, 0x09, 0x29, 0x61, 0x18, 0x3e, 0x82, 0x45, 0xab, 0x7e, 0x02, 0x0b, 0xa3, 0x4c, 0x54, + 0x27, 0x86, 0xf7, 0x95, 0x48, 0x27, 0x00, 0x32, 0x0f, 0xb6, 0x1a, 0x8f, 0x77, 0xea, 0xa5, 0x94, + 0xfa, 0x8b, 0x0c, 0x79, 0x5a, 0x81, 0xed, 0xc3, 0xbe, 0x75, 0x84, 0xf6, 0xd8, 0x36, 0x32, 0x88, + 0x3b, 0x73, 0xe2, 0x29, 0x94, 0x18, 0x98, 0x78, 0x76, 0xdf, 0x6d, 0x53, 0x55, 0x31, 0x88, 0xcb, + 0xe3, 0xe1, 0xc6, 0x9a, 0x84, 0x45, 0x0f, 0x69, 0xfc, 0xda, 0x29, 0x14, 0x60, 0xe3, 0x1c, 0x74, + 0xec, 0x91, 0x97, 0x94, 0x5a, 0x6a, 0x12, 0x66, 0x6d, 0x2d, 0x0b, 0xe9, 0x36, 0x7d, 0xa5, 0xbe, + 0x95, 0xe1, 0x4a, 0x62, 0x08, 0x17, 0x9a, 0x33, 0x15, 0x32, 0x8c, 0x9e, 0xcf, 0x59, 0x9a, 0xa7, + 0xc3, 0x47, 0xb0, 0x68, 0xd1, 0x06, 0xe4, 0xda, 0x87, 0xa4, 0x7d, 0xe4, 0xf5, 0x7b, 0x62, 0x12, + 0x98, 0x4e, 0x47, 0x63, 0x78, 0xd0, 0x43, 0x1f, 0x03, 0x30, 0x9b, 0x96, 0x67, 0xbe, 0x21, 0x4c, + 0xd3, 0xd3, 0xe2, 0x9f, 0x82, 0xc1, 0x28, 0xce, 0xb3, 0xfe, 0x13, 0xf3, 0x0d, 0x51, 0x7f, 0x94, + 0x61, 0x39, 0xa9, 0x0c, 0x17, 0xca, 0x68, 0x9d, 0x46, 0x4b, 0xbd, 0x99, 0x86, 0xc8, 0x49, 0x44, + 0xcb, 0xc7, 0x70, 0x96, 0xf5, 0x1a, 0x06, 0xba, 0x21, 0xe6, 0x88, 0xa6, 0x54, 0x1c, 0x56, 0x5e, + 0xd4, 0xfd, 0xee, 0xaf, 0xef, 0x56, 0xe5, 0xb7, 0xef, 0x56, 0xe5, 0xdf, 0xdf, 0xad, 0xca, 0x2f, + 0x6e, 0x75, 0x4d, 0xff, 0xb0, 0xff, 0xb2, 0xd2, 0xb6, 0x7b, 0x55, 0x16, 0x49, 0x95, 0x45, 0x52, + 0xf5, 0x8c, 0xa3, 0xea, 0xc9, 0x66, 0x95, 0xfd, 0xc3, 0x73, 0x9f, 0xfd, 0xbe, 0xcc, 0xb0, 0xe6, + 0xce, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc1, 0x1f, 0x57, 0x17, 0x9b, 0x12, 0x00, 0x00, } func (m *Command) Marshal() (dAtA []byte, err error) { @@ -1884,6 +1892,13 @@ func (m *NginxConfigStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.NginxId) > 0 { + i -= len(m.NginxId) + copy(dAtA[i:], m.NginxId) + i = encodeVarintCommand(dAtA, i, uint64(len(m.NginxId))) + i-- + dAtA[i] = 0x22 + } if len(m.Message) > 0 { i -= len(m.Message) copy(dAtA[i:], m.Message) @@ -2653,6 +2668,10 @@ func (m *NginxConfigStatus) Size() (n int) { if l > 0 { n += 1 + l + sovCommand(uint64(l)) } + l = len(m.NginxId) + if l > 0 { + n += 1 + l + sovCommand(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -4007,6 +4026,38 @@ func (m *NginxConfigStatus) Unmarshal(dAtA []byte) error { } m.Message = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NginxId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommand + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommand + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommand + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NginxId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommand(dAtA[iNdEx:]) diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/command.proto b/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/command.proto index 4ae215aa5..feb738c3c 100644 --- a/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/command.proto +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/command.proto @@ -103,6 +103,7 @@ message NginxConfigStatus { string correlation_id = 1 [(gogoproto.jsontag) = "correlation_id" ]; Status status = 2 [(gogoproto.jsontag) = "status" ]; string message = 3 [(gogoproto.jsontag) = "message" ]; + string nginx_id = 4 [(gogoproto.jsontag) = "nginx_id" ]; enum Status { PENDING = 0; diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/types.go b/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/types.go index c65dec245..4ced9dcb3 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/types.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/types.go @@ -38,6 +38,23 @@ type Config struct { NAPMonitoring NAPMonitoring `mapstructure:"nap_monitoring" yaml:"nap_monitoring,omitempty"` } +func (c *Config) IsGrpcServerConfigured() bool { + return c.Server.Host != "" && c.Server.GrpcPort != 0 +} + +func (c *Config) IsNginxAppProtectConfigured() bool { + return c.NginxAppProtect != (NginxAppProtect{}) +} + +func (c *Config) IsFeatureEnabled(feature string) bool { + for _, configFeature := range c.Features { + if configFeature == feature { + return true + } + } + return false +} + type Server struct { Host string `mapstructure:"host" yaml:"-"` GrpcPort int `mapstructure:"grpcPort" yaml:"-"` diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/core/nginx.go b/test/performance/vendor/github.com/nginx/agent/v2/src/core/nginx.go index 93cd0eca4..4b8f1e747 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/core/nginx.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/core/nginx.go @@ -258,9 +258,11 @@ func (n *NginxBinaryType) ValidateConfig(processId, bin, configLocation string, log.Debugf("Validating config, %s for nginx process, %s", configLocation, processId) response, err := runCmd(bin, "-t", "-c", configLocation) if err != nil { - confFiles, auxFiles, err := sdk.GetNginxConfigFiles(config) - n.writeBackup(config, confFiles, auxFiles) - return fmt.Errorf("error running nginx -t -c %v:\n%s%v", configLocation, response, err) + confFiles, auxFiles, getNginxConfigFilesErr := sdk.GetNginxConfigFiles(config) + if getNginxConfigFilesErr == nil { + n.writeBackup(config, confFiles, auxFiles) + } + return fmt.Errorf("error running nginx -t -c %v:\n%s", configLocation, response) } log.Infof("Config validated:\n%s", response) diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/core/topics.go b/test/performance/vendor/github.com/nginx/agent/v2/src/core/topics.go index 58b00804c..67a6e1ff0 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/core/topics.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/core/topics.go @@ -52,4 +52,5 @@ const ( ConfigRollbackResponse = "config.rollback.response" DataplaneSoftwareDetailsUpdated = "dataplane.software.details.updated" EnableExtension = "enable.extension" + AgentAPIConfigApplyResponse = "agent.api.config.apply.response" ) diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/agent_api.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/agent_api.go index 7c6463497..fe6346543 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/agent_api.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/agent_api.go @@ -12,9 +12,14 @@ import ( "context" "encoding/json" "fmt" + "io" "net/http" + "os" "regexp" + "time" + "github.com/google/uuid" + "github.com/nginx/agent/sdk/v2" "github.com/nginx/agent/sdk/v2/proto" "github.com/nginx/agent/v2/src/core" "github.com/nginx/agent/v2/src/core/config" @@ -24,9 +29,23 @@ import ( log "github.com/sirupsen/logrus" ) +const ( + okStatus = "OK" + pendingStatus = "PENDING" + errorStatus = "ERROR" + unknownStatus = "UNKNOWN" +) + +var ( + instancesRegex = regexp.MustCompile(`^\/nginx[\/]*$`) + configRegex = regexp.MustCompile(`^\/nginx/config[\/]*$`) + configStatusRegex = regexp.MustCompile(`^\/nginx/config/status[\/]*$`) +) + type AgentAPI struct { config *config.Config env core.Environment + pipeline core.MessagePipeInterface server http.Server nginxBinary core.NginxBinary nginxHandler *NginxHandler @@ -34,8 +53,39 @@ type AgentAPI struct { } type NginxHandler struct { - env core.Environment - nginxBinary core.NginxBinary + config *config.Config + env core.Environment + pipeline core.MessagePipeInterface + nginxBinary core.NginxBinary + responseChannel chan *proto.Command_NginxConfigResponse + configResponseStatuses map[string]*proto.NginxConfigStatus +} + +type AgentAPIConfigApplyRequest struct { + correlationId string + config *proto.NginxConfig +} + +type NginxInstanceResponse struct { + NginxId string `json:"nginx_id"` + Message string `json:"message"` + Status string `json:"status"` +} + +type AgentAPIConfigApplyResponse struct { + CorrelationId string `json:"correlation_id"` + NginxInstances []NginxInstanceResponse `json:"nginx_instances"` +} + +type AgentAPICommonResponse struct { + CorrelationId string `json:"correlation_id"` + Message string `json:"message"` +} + +type AgentAPIConfigApplyStatusResponse struct { + CorrelationId string `json:"correlation_id"` + Message string `json:"message"` + Status string `json:"status"` } const ( @@ -43,16 +93,18 @@ const ( jsonMimeType = "application/json" ) -var ( - instancesRegex = regexp.MustCompile(`^\/nginx[\/]*$`) -) - func NewAgentAPI(config *config.Config, env core.Environment, nginxBinary core.NginxBinary) *AgentAPI { - return &AgentAPI{config: config, env: env, nginxBinary: nginxBinary, exporter: prometheus_metrics.NewExporter(&proto.MetricsReport{})} + return &AgentAPI{ + config: config, + env: env, + nginxBinary: nginxBinary, + exporter: prometheus_metrics.NewExporter(&proto.MetricsReport{}), + } } -func (a *AgentAPI) Init(core.MessagePipeInterface) { +func (a *AgentAPI) Init(pipeline core.MessagePipeInterface) { log.Info("Agent API initializing") + a.pipeline = pipeline go a.createHttpServer() } @@ -65,15 +117,31 @@ func (a *AgentAPI) Close() { func (a *AgentAPI) Process(message *core.Message) { log.Tracef("Process function in the agent_api.go, %s %v", message.Topic(), message.Data()) - switch { - case message.Exact(core.MetricReport): - metricReport, ok := message.Data().(*proto.MetricsReport) - if !ok { - log.Warnf("Invalid message received, %T, for topic, %s", message.Data(), message.Topic()) - return + + switch message.Topic() { + case core.AgentAPIConfigApplyResponse: + switch response := message.Data().(type) { + case *proto.Command_NginxConfigResponse: + a.nginxHandler.responseChannel <- response + default: + log.Warnf("Unknown Command_NginxConfigResponse type: %T(%v)", message.Data(), message.Data()) + } + case core.MetricReport: + switch response := message.Data().(type) { + case *proto.MetricsReport: + a.exporter.SetLatestMetricReport(response) + default: + log.Warnf("Unknown MetricReport type: %T(%v)", message.Data(), message.Data()) + } + case core.NginxConfigValidationPending, core.NginxConfigApplyFailed, core.NginxConfigApplySucceeded: + switch response := message.Data().(type) { + case *proto.AgentActivityStatus: + log.Error(response) + nginxConfigStatus := response.GetNginxConfigStatus() + a.nginxHandler.configResponseStatuses[nginxConfigStatus.GetNginxId()] = nginxConfigStatus + default: + log.Errorf("Expected the type %T but got %T", &proto.AgentActivityStatus{}, response) } - a.exporter.SetLatestMetricReport(metricReport) - return } } func (a *AgentAPI) Info() *core.Info { @@ -81,18 +149,31 @@ func (a *AgentAPI) Info() *core.Info { } func (a *AgentAPI) Subscriptions() []string { - return []string{core.MetricReport} + return []string{ + core.AgentAPIConfigApplyResponse, + core.MetricReport, + core.NginxConfigValidationPending, + core.NginxConfigApplyFailed, + core.NginxConfigApplySucceeded, + } } func (a *AgentAPI) createHttpServer() { + a.nginxHandler = &NginxHandler{ + config: a.config, + pipeline: a.pipeline, + env: a.env, + nginxBinary: a.nginxBinary, + responseChannel: make(chan *proto.Command_NginxConfigResponse), + configResponseStatuses: make(map[string]*proto.NginxConfigStatus), + } + mux := http.NewServeMux() - a.nginxHandler = &NginxHandler{a.env, a.nginxBinary} registerer := prometheus.DefaultRegisterer gatherer := prometheus.DefaultGatherer registerer.MustRegister(a.exporter) mux.Handle("/metrics/", promhttp.HandlerFor(gatherer, promhttp.HandlerOpts{})) - mux.Handle("/nginx/", a.nginxHandler) a.server = http.Server{ @@ -118,11 +199,36 @@ func (a *AgentAPI) createHttpServer() { func (h *NginxHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Header().Set(contentTypeHeader, jsonMimeType) switch { - case r.Method == http.MethodGet && instancesRegex.MatchString(r.URL.Path): - err := sendInstanceDetailsPayload(h.getNginxDetails(), w, r) + case instancesRegex.MatchString(r.URL.Path): + if r.Method != http.MethodGet { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + + err := h.sendInstanceDetailsPayload(w, r) if err != nil { log.Warnf("Failed to send instance details payload: %v", err) } + case configRegex.MatchString(r.URL.Path): + if r.Method != http.MethodPut { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + + err := h.updateConfig(w, r) + if err != nil { + log.Warnf("Failed to update config: %v", err) + } + case configStatusRegex.MatchString(r.URL.Path): + if r.Method != http.MethodGet { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + + err := h.getConfigStatus(w, r) + if err != nil { + log.Warnf("Failed to get config status: %v", err) + } default: w.WriteHeader(http.StatusNotFound) _, err := fmt.Fprint(w, []byte("not found")) @@ -132,7 +238,8 @@ func (h *NginxHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } } -func sendInstanceDetailsPayload(nginxDetails []*proto.NginxDetails, w http.ResponseWriter, r *http.Request) error { +func (h *NginxHandler) sendInstanceDetailsPayload(w http.ResponseWriter, r *http.Request) error { + nginxDetails := h.getNginxDetails() w.WriteHeader(http.StatusOK) if len(nginxDetails) == 0 { @@ -145,20 +252,108 @@ func sendInstanceDetailsPayload(nginxDetails []*proto.NginxDetails, w http.Respo return nil } - respBody := new(bytes.Buffer) - err := json.NewEncoder(respBody).Encode(nginxDetails) + return writeObjectToResponseBody(w, nginxDetails) +} + +func (h *NginxHandler) updateConfig(w http.ResponseWriter, r *http.Request) error { + correlationId := uuid.New().String() + + buf, err := readFileFromRequest(r) if err != nil { - return fmt.Errorf("failed to encode payload: %v", err) + w.WriteHeader(http.StatusBadRequest) + response := AgentAPICommonResponse{ + CorrelationId: correlationId, + Message: err.Error(), + } + return writeObjectToResponseBody(w, response) } - _, err = fmt.Fprint(w, respBody) - if err != nil { - return fmt.Errorf("failed to send payload: %v", err) + nginxDetails := h.getNginxDetails() + + for _, nginxDetail := range nginxDetails { + err := h.applyNginxConfig(nginxDetail, buf, correlationId) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + response := AgentAPICommonResponse{ + CorrelationId: correlationId, + Message: err.Error(), + } + return writeObjectToResponseBody(w, response) + } } + if len(nginxDetails) > 0 { + agentAPIConfigApplyResponse := &AgentAPIConfigApplyResponse{CorrelationId: correlationId, NginxInstances: make([]NginxInstanceResponse, 0)} + + select { + case response := <-h.responseChannel: + nginxResponse := NginxInstanceResponse{ + NginxId: response.NginxConfigResponse.GetConfigData().GetNginxId(), + Message: response.NginxConfigResponse.GetStatus().GetMessage(), + Status: okStatus, + } + + if response.NginxConfigResponse.GetStatus().GetStatus() != proto.CommandStatusResponse_CMD_OK { + w.WriteHeader(http.StatusBadRequest) + nginxResponse.Status = errorStatus + } else { + if response.NginxConfigResponse.GetStatus().GetMessage() == configAppliedProcessedResponse { + w.WriteHeader(http.StatusRequestTimeout) + nginxResponse.Status = pendingStatus + } else { + w.WriteHeader(http.StatusOK) + } + } + + agentAPIConfigApplyResponse.NginxInstances = append(agentAPIConfigApplyResponse.NginxInstances, nginxResponse) + + // If the number of responses match the number of NGINX instances then return a response. + // Otherwise wait until all config apply requests are complete for all NGINX instances. + if len(agentAPIConfigApplyResponse.NginxInstances) == len(nginxDetails) { + return writeObjectToResponseBody(w, agentAPIConfigApplyResponse) + } + + case <-time.After(validationTimeout): + w.WriteHeader(http.StatusRequestTimeout) + agentAPIConfigApplyStatusResponse := AgentAPIConfigApplyStatusResponse{ + CorrelationId: correlationId, + Message: "Pending config apply", + Status: pendingStatus, + } + + return writeObjectToResponseBody(w, agentAPIConfigApplyStatusResponse) + } + } else { + w.WriteHeader(http.StatusInternalServerError) + response := AgentAPICommonResponse{ + CorrelationId: correlationId, + Message: "No NGINX instances found", + } + return writeObjectToResponseBody(w, response) + } + + w.WriteHeader(http.StatusInternalServerError) return nil } +func readFileFromRequest(r *http.Request) (*bytes.Buffer, error) { + err := r.ParseMultipartForm(32 << 20) + if err != nil { + log.Errorf("unable to parse config apply request, %v", err) + } + file, _, err := r.FormFile("file") + if err != nil { + return nil, fmt.Errorf("can't read form file: %v", err) + } + defer file.Close() + + buf := bytes.NewBuffer(nil) + if _, err := io.Copy(buf, file); err != nil { + return nil, fmt.Errorf("can't read file, %v", err) + } + return buf, nil +} + func (h *NginxHandler) getNginxDetails() []*proto.NginxDetails { var nginxDetails []*proto.NginxDetails @@ -169,3 +364,109 @@ func (h *NginxHandler) getNginxDetails() []*proto.NginxDetails { } return nginxDetails } + +func (h *NginxHandler) applyNginxConfig(nginxDetail *proto.NginxDetails, buf *bytes.Buffer, correlationId string) error { + fullFilePath := nginxDetail.ConfPath + + // Create backup of nginx.conf file on host + data, err := os.ReadFile(fullFilePath) + if err != nil { + return fmt.Errorf("unable to read file %s: %v", fullFilePath, err) + } + + protoFile := &proto.File{ + Name: fullFilePath, + Permissions: "0755", + Contents: buf.Bytes(), + } + + configApply, err := sdk.NewConfigApply(protoFile.GetName(), h.config.AllowedDirectoriesMap) + if err != nil { + return fmt.Errorf("unable to write config: %v", err) + } + + // Temporarily write the new nginx.conf to disk + err = h.env.WriteFiles(configApply, []*proto.File{protoFile}, "", h.config.AllowedDirectoriesMap) + if err != nil { + rollbackErr := configApply.Rollback(err) + return fmt.Errorf("config rollback failed: %v", rollbackErr) + } + + // Create NginxConfig object for new nginx.conf + conf, err := h.nginxBinary.ReadConfig(fullFilePath, nginxDetail.NginxId, h.env.GetSystemUUID()) + if err != nil { + rollbackErr := configApply.Rollback(err) + return fmt.Errorf("unable to read config: %v", rollbackErr) + } + + // Write back the original nginx.conf + err = os.WriteFile(fullFilePath, data, 0644) + if err != nil { + rollbackErr := configApply.Rollback(err) + return fmt.Errorf("unable to write file %s: %v", fullFilePath, rollbackErr) + } + + // Send a config apply request to the nginx.go plugin + h.pipeline.Process(core.NewMessage(core.CommNginxConfig, &AgentAPIConfigApplyRequest{correlationId: correlationId, config: conf})) + return nil +} + +func (h *NginxHandler) getConfigStatus(w http.ResponseWriter, r *http.Request) error { + correlationId := r.URL.Query().Get("correlation_id") + + if correlationId == "" { + w.WriteHeader(http.StatusBadRequest) + + agentAPIConfigApplyStatusResponse := AgentAPIConfigApplyStatusResponse{ + CorrelationId: correlationId, + Message: "Missing required query parameter correlation_id", + Status: unknownStatus, + } + + return writeObjectToResponseBody(w, agentAPIConfigApplyStatusResponse) + } + + agentAPIConfigApplyStatusResponse := AgentAPIConfigApplyResponse{ + CorrelationId: correlationId, + NginxInstances: []NginxInstanceResponse{}, + } + + for _, nginxConfigStatus := range h.configResponseStatuses { + if nginxConfigStatus.GetCorrelationId() == correlationId { + nginxInstanceResponse := NginxInstanceResponse{ + NginxId: nginxConfigStatus.GetNginxId(), + Message: nginxConfigStatus.GetMessage(), + Status: nginxConfigStatus.GetStatus().String(), + } + agentAPIConfigApplyStatusResponse.NginxInstances = append(agentAPIConfigApplyStatusResponse.NginxInstances, nginxInstanceResponse) + } + } + + if len(agentAPIConfigApplyStatusResponse.NginxInstances) == 0 { + w.WriteHeader(http.StatusNotFound) + agentAPIConfigApplyStatusResponse := AgentAPIConfigApplyStatusResponse{ + CorrelationId: correlationId, + Message: fmt.Sprintf("Unable to find a config apply request with the correlation_id %s", correlationId), + Status: unknownStatus, + } + + return writeObjectToResponseBody(w, agentAPIConfigApplyStatusResponse) + } + + w.WriteHeader(http.StatusOK) + return writeObjectToResponseBody(w, agentAPIConfigApplyStatusResponse) +} + +func writeObjectToResponseBody(w http.ResponseWriter, response any) error { + respBody := new(bytes.Buffer) + err := json.NewEncoder(respBody).Encode(response) + if err != nil { + return fmt.Errorf("failed to encode payload: %v", err) + } + + _, err = fmt.Fprint(w, respBody) + if err != nil { + return fmt.Errorf("failed to send payload: %v", err) + } + return nil +} diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/dataplane_status.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/dataplane_status.go index 255ff91c8..dc6a433f2 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/dataplane_status.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/dataplane_status.go @@ -23,25 +23,25 @@ import ( ) type DataPlaneStatus struct { - messagePipeline core.MessagePipeInterface - ctx context.Context - sendStatus chan bool - healthTicker *time.Ticker - interval time.Duration - meta *proto.Metadata - binary core.NginxBinary - env core.Environment - version string - tags *[]string - configDirs string - lastSendDetails time.Time - envHostInfo *proto.HostInfo - statusUrls map[string]string - reportInterval time.Duration - napDetails *proto.DataplaneSoftwareDetails_AppProtectWafDetails - agentActivityStatuses []*proto.AgentActivityStatus - napDetailsMutex sync.RWMutex - napHealth *proto.DataplaneSoftwareHealth_AppProtectWafHealth + messagePipeline core.MessagePipeInterface + ctx context.Context + sendStatus chan bool + healthTicker *time.Ticker + interval time.Duration + meta *proto.Metadata + binary core.NginxBinary + env core.Environment + version string + tags *[]string + configDirs string + lastSendDetails time.Time + envHostInfo *proto.HostInfo + statusUrls map[string]string + reportInterval time.Duration + napDetails *proto.DataplaneSoftwareDetails_AppProtectWafDetails + nginxConfigActivityStatuses map[string]*proto.AgentActivityStatus + napDetailsMutex sync.RWMutex + napHealth *proto.DataplaneSoftwareHealth_AppProtectWafHealth } const ( @@ -56,18 +56,19 @@ func NewDataPlaneStatus(config *config.Config, meta *proto.Metadata, binary core log.Warnf("interval set to %s, provided value (%s) less than minimum", pollInt, config.Dataplane.Status.PollInterval) } return &DataPlaneStatus{ - sendStatus: make(chan bool), - healthTicker: time.NewTicker(pollInt), - interval: pollInt, - meta: meta, - binary: binary, - env: env, - version: version, - tags: &config.Tags, - configDirs: config.ConfigDirs, - statusUrls: make(map[string]string), - reportInterval: config.Dataplane.Status.ReportInterval, - napDetailsMutex: sync.RWMutex{}, + sendStatus: make(chan bool), + healthTicker: time.NewTicker(pollInt), + interval: pollInt, + meta: meta, + binary: binary, + env: env, + version: version, + tags: &config.Tags, + configDirs: config.ConfigDirs, + statusUrls: make(map[string]string), + reportInterval: config.Dataplane.Status.ReportInterval, + napDetailsMutex: sync.RWMutex{}, + nginxConfigActivityStatuses: make(map[string]*proto.AgentActivityStatus), // Intentionally empty as it will be set later napDetails: nil, napHealth: &proto.DataplaneSoftwareHealth_AppProtectWafHealth{}, @@ -112,7 +113,7 @@ func (dps *DataPlaneStatus) Process(msg *core.Message) { log.Tracef("DataplaneStatus: %T message from topic %s received", msg.Data(), msg.Topic()) switch data := msg.Data().(type) { case *proto.AgentActivityStatus: - dps.updateAgentActivityStatuses(data) + dps.updateNginxConfigActivityStatuses(data) default: log.Errorf("Expected the type %T but got %T", &proto.AgentActivityStatus{}, data) } @@ -121,9 +122,8 @@ func (dps *DataPlaneStatus) Process(msg *core.Message) { log.Tracef("DataplaneStatus: %T message from topic %s received", msg.Data(), msg.Topic()) switch data := msg.Data().(type) { case *proto.AgentActivityStatus: - dps.updateAgentActivityStatuses(data) + dps.updateNginxConfigActivityStatuses(data) dps.sendDataplaneStatus(dps.messagePipeline, false) - dps.removeAgentActivityStatus(data) default: log.Errorf("Expected the type %T but got %T", &proto.AgentActivityStatus{}, data) } @@ -140,34 +140,10 @@ func (dps *DataPlaneStatus) Subscriptions() []string { } } -func (dps *DataPlaneStatus) updateAgentActivityStatuses(newAgentActivityStatus *proto.AgentActivityStatus) { - log.Tracef("DataplaneStatus: Adding %v to agentActivityStatuses", newAgentActivityStatus) +func (dps *DataPlaneStatus) updateNginxConfigActivityStatuses(newAgentActivityStatus *proto.AgentActivityStatus) { + log.Tracef("DataplaneStatus: Updating nginxConfigActivityStatuses with %v", newAgentActivityStatus) if _, ok := newAgentActivityStatus.GetStatus().(*proto.AgentActivityStatus_NginxConfigStatus); ok { - foundExistingNginxStatus := false - for index, agentActivityStatus := range dps.agentActivityStatuses { - if _, ok := agentActivityStatus.GetStatus().(*proto.AgentActivityStatus_NginxConfigStatus); ok { - dps.agentActivityStatuses[index] = newAgentActivityStatus - log.Tracef("DataplaneStatus: Updated agentActivityStatus with new status %v", newAgentActivityStatus) - foundExistingNginxStatus = true - } - } - - if !foundExistingNginxStatus { - dps.agentActivityStatuses = append(dps.agentActivityStatuses, newAgentActivityStatus) - log.Tracef("DataplaneStatus: Added new status %v to agentActivityStatus", newAgentActivityStatus) - } - } -} - -func (dps *DataPlaneStatus) removeAgentActivityStatus(agentActivityStatus *proto.AgentActivityStatus) { - log.Tracef("DataplaneStatus: Removing %v from agentActivityStatuses", agentActivityStatus) - if _, ok := agentActivityStatus.GetStatus().(*proto.AgentActivityStatus_NginxConfigStatus); ok { - for index, agentActivityStatus := range dps.agentActivityStatuses { - if _, ok := agentActivityStatus.GetStatus().(*proto.AgentActivityStatus_NginxConfigStatus); ok { - dps.agentActivityStatuses = append(dps.agentActivityStatuses[:index], dps.agentActivityStatuses[index+1:]...) - log.Tracef("DataplaneStatus: Removed %v from agentActivityStatus", agentActivityStatus) - } - } + dps.nginxConfigActivityStatuses[newAgentActivityStatus.GetNginxConfigStatus().GetNginxId()] = newAgentActivityStatus } } @@ -205,12 +181,18 @@ func (dps *DataPlaneStatus) dataplaneStatus(forceDetails bool) *proto.DataplaneS processes := dps.env.Processes() log.Tracef("dataplaneStatus: processes %v", processes) forceDetails = forceDetails || time.Now().UTC().Add(-dps.reportInterval).After(dps.lastSendDetails) + + agentActivityStatuses := []*proto.AgentActivityStatus{} + for _, nginxConfigActivityStatus := range dps.nginxConfigActivityStatuses { + agentActivityStatuses = append(agentActivityStatuses, nginxConfigActivityStatus) + } + return &proto.DataplaneStatus{ Host: dps.hostInfo(forceDetails), Details: dps.detailsForProcess(processes, forceDetails), Healths: dps.healthForProcess(processes), DataplaneSoftwareDetails: dps.dataplaneSoftwareDetails(), - AgentActivityStatus: dps.agentActivityStatuses, + AgentActivityStatus: agentActivityStatuses, } } diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/nginx.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/nginx.go index 334c9653b..a111b4019 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/nginx.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/nginx.go @@ -31,23 +31,28 @@ import ( "github.com/nginx/agent/v2/src/extensions/nginx-app-protect/nap" ) +const ( + configAppliedProcessedResponse = "config apply request successfully processed" + configAppliedResponse = "config applied successfully" +) + var ( validationTimeout = 15 * time.Second ) // Nginx is the metadata of our nginx binary type Nginx struct { - messagePipeline core.MessagePipeInterface - nginxBinary core.NginxBinary - processes []core.Process - env core.Environment - cmdr client.Commander - config *config.Config - isNAPEnabled bool - isConfUploadEnabled bool - configApplyStatusChannel chan *proto.Command_NginxConfigResponse - wafVersion string - wafLocation string + messagePipeline core.MessagePipeInterface + nginxBinary core.NginxBinary + processes []core.Process + env core.Environment + cmdr client.Commander + config *config.Config + isNAPEnabled bool + isFeatureNginxConfigEnabled bool + configApplyStatusChannel chan *proto.Command_NginxConfigResponse + wafVersion string + wafLocation string } type ConfigRollbackResponse struct { @@ -74,23 +79,19 @@ type NginxConfigValidationResponse struct { } func NewNginx(cmdr client.Commander, nginxBinary core.NginxBinary, env core.Environment, loadedConfig *config.Config) *Nginx { - var isNAPEnabled bool - if loadedConfig.NginxAppProtect != (config.NginxAppProtect{}) { - isNAPEnabled = true - } - - isConfUploadEnabled := isConfUploadEnabled(loadedConfig) + isNAPEnabled := loadedConfig.IsNginxAppProtectConfigured() + isFeatureNginxConfigEnabled := loadedConfig.IsFeatureEnabled(agent_config.FeatureNginxConfig) return &Nginx{ - nginxBinary: nginxBinary, - processes: env.Processes(), - env: env, - cmdr: cmdr, - config: loadedConfig, - isNAPEnabled: isNAPEnabled, - isConfUploadEnabled: isConfUploadEnabled, - configApplyStatusChannel: make(chan *proto.Command_NginxConfigResponse, 1), - wafLocation: nap.APP_PROTECT_METADATA_FILE_PATH, + nginxBinary: nginxBinary, + processes: env.Processes(), + env: env, + cmdr: cmdr, + config: loadedConfig, + isNAPEnabled: isNAPEnabled, + isFeatureNginxConfigEnabled: isFeatureNginxConfigEnabled, + configApplyStatusChannel: make(chan *proto.Command_NginxConfigResponse, 1), + wafLocation: nap.APP_PROTECT_METADATA_FILE_PATH, } } @@ -114,7 +115,13 @@ func (n *Nginx) Process(message *core.Message) { switch cmd := message.Data().(type) { case *proto.Command: n.processCmd(cmd) + case *AgentAPIConfigApplyRequest: + status := n.writeConfigAndReloadNginx(cmd.correlationId, cmd.config, proto.NginxConfigAction_APPLY) + if status.NginxConfigResponse.GetStatus().GetMessage() != configAppliedProcessedResponse { + n.messagePipeline.Process(core.NewMessage(core.AgentAPIConfigApplyResponse, status)) + } } + case core.NginxConfigUpload: switch cfg := message.Data().(type) { case *proto.ConfigDescriptor: @@ -187,7 +194,7 @@ func (n *Nginx) Subscriptions() []string { func (n *Nginx) uploadConfig(config *proto.ConfigDescriptor, messageId string) error { log.Debugf("Uploading config for %v", config) - if !n.isConfUploadEnabled { + if !n.isFeatureNginxConfigEnabled { log.Info("unable to upload config as nginx-config feature is disabled") return nil } @@ -245,7 +252,7 @@ func (n *Nginx) processCmd(cmd *proto.Command) { switch commandData.NginxConfig.Action { case proto.NginxConfigAction_APPLY, proto.NginxConfigAction_FORCE: - if n.isConfUploadEnabled { + if n.isFeatureNginxConfigEnabled { status = n.applyConfig(cmd, commandData) } else { log.Warnf("unable to upload config as nginx-config feature is disabled") @@ -279,20 +286,9 @@ func (n *Nginx) processCmd(cmd *proto.Command) { func (n *Nginx) applyConfig(cmd *proto.Command, cfg *proto.Command_NginxConfig) (status *proto.Command_NginxConfigResponse) { log.Debugf("Applying config for message id, %s", cmd.GetMeta().MessageId) - - n.messagePipeline.Process(core.NewMessage(core.NginxConfigValidationPending, &proto.AgentActivityStatus{ - Status: &proto.AgentActivityStatus_NginxConfigStatus{ - NginxConfigStatus: &proto.NginxConfigStatus{ - CorrelationId: cmd.Meta.MessageId, - Status: proto.NginxConfigStatus_PENDING, - Message: "config apply pending", - }, - }, - })) - status = &proto.Command_NginxConfigResponse{ NginxConfigResponse: &proto.NginxConfigResponse{ - Status: newOKStatus("config apply request successfully processed").CmdStatus, + Status: newOKStatus(configAppliedProcessedResponse).CmdStatus, Action: proto.NginxConfigAction_APPLY, ConfigData: cfg.NginxConfig.ConfigData, }, @@ -304,13 +300,44 @@ func (n *Nginx) applyConfig(cmd *proto.Command, cfg *proto.Command_NginxConfig) return status } + if err != nil { + status.NginxConfigResponse.Status = newErrStatus("Config apply failed: " + err.Error()).CmdStatus + return status + } + + status = n.writeConfigAndReloadNginx(cmd.Meta.MessageId, config, cmd.GetNginxConfig().GetAction()) + + log.Debug("Config Apply Complete") + return status +} + +func (n *Nginx) writeConfigAndReloadNginx(correlationId string, config *proto.NginxConfig, action proto.NginxConfigAction) *proto.Command_NginxConfigResponse { + status := &proto.Command_NginxConfigResponse{ + NginxConfigResponse: &proto.NginxConfigResponse{ + Status: newOKStatus(configAppliedProcessedResponse).CmdStatus, + Action: proto.NginxConfigAction_APPLY, + ConfigData: config.ConfigData, + }, + } + + n.messagePipeline.Process(core.NewMessage(core.NginxConfigValidationPending, &proto.AgentActivityStatus{ + Status: &proto.AgentActivityStatus_NginxConfigStatus{ + NginxConfigStatus: &proto.NginxConfigStatus{ + CorrelationId: correlationId, + Status: proto.NginxConfigStatus_PENDING, + Message: "config apply pending", + NginxId: config.GetConfigData().GetNginxId(), + }, + }, + })) + if config.GetConfigData().GetNginxId() == "" { status.NginxConfigResponse.Status = newErrStatus(fmt.Sprintf("Config apply failed (preflight): no Nginx Id in ConfigDescriptor %v", config.GetConfigData())).CmdStatus return status } - if cmd.GetNginxConfig().GetAction() != proto.NginxConfigAction_FORCE { - if isNapInPayload(config.GetDirectoryMap(), cmd.GetNginxConfig().GetAction(), n.wafLocation) { + if action != proto.NginxConfigAction_FORCE { + if isNapInPayload(config.GetDirectoryMap(), action, n.wafLocation) { if aux := config.GetZaux(); aux != nil && len(aux.Contents) > 0 { auxFiles, err := zip.UnPack(aux) if err != nil { @@ -340,12 +367,12 @@ func (n *Nginx) applyConfig(cmd *proto.Command, cfg *proto.Command_NginxConfig) n.messagePipeline.Process(core.NewMessage(core.FileWatcherEnabled, false)) nginx := n.nginxBinary.GetNginxDetailsByID(config.GetConfigData().GetNginxId()) - if nginx == nil || nginx == (&proto.NginxDetails{}) { message := fmt.Sprintf("Config apply failed (preflight): no Nginx instance found for %v", config.GetConfigData().GetNginxId()) return n.handleErrorStatus(status, message) } + log.Debugf("WriteConfig start %v", config) configApply, err := n.nginxBinary.WriteConfig(config) if err != nil { if configApply != nil { @@ -358,7 +385,7 @@ func (n *Nginx) applyConfig(cmd *proto.Command, cfg *proto.Command_NginxConfig) configRollbackResponse := ConfigRollbackResponse{ succeeded: succeeded, - correlationId: cmd.Meta.MessageId, + correlationId: correlationId, timestamp: types.TimestampNow(), nginxDetails: nginx, } @@ -366,21 +393,10 @@ func (n *Nginx) applyConfig(cmd *proto.Command, cfg *proto.Command_NginxConfig) } message := fmt.Sprintf("Config apply failed (write): " + err.Error()) - - n.messagePipeline.Process(core.NewMessage(core.NginxConfigApplyFailed, &proto.AgentActivityStatus{ - Status: &proto.AgentActivityStatus_NginxConfigStatus{ - NginxConfigStatus: &proto.NginxConfigStatus{ - CorrelationId: cmd.Meta.MessageId, - Status: proto.NginxConfigStatus_ERROR, - Message: message, - }, - }, - })) - return n.handleErrorStatus(status, message) } - go n.validateConfig(nginx, cmd.Meta.MessageId, config, configApply) + go n.validateConfig(nginx, correlationId, config, configApply) // If the NGINX config can be validated with the validationTimeout the result will be returned straight away. // This is timeout is temporary to ensure we support backwards compatibility. In a future release this timeout @@ -389,7 +405,7 @@ func (n *Nginx) applyConfig(cmd *proto.Command, cfg *proto.Command_NginxConfig) case result := <-n.configApplyStatusChannel: return result case <-time.After(validationTimeout): - log.Debugf("Validation of the NGINX config in taking longer than the validationTimeout %s", validationTimeout) + log.Errorf("Validation of the NGINX config in taking longer than the validationTimeout %s", validationTimeout) return status } } @@ -445,7 +461,7 @@ func (n *Nginx) validateConfig(nginx *proto.NginxDetails, correlationId string, } func (n *Nginx) completeConfigApply(response *NginxConfigValidationResponse) *proto.Command_NginxConfigResponse { - nginxConfigStatusMessage := "Config applied successfully" + nginxConfigStatusMessage := configAppliedResponse if response.configApply != nil { if err := response.configApply.Complete(); err != nil { nginxConfigStatusMessage = fmt.Sprintf("Config complete failed: %v", err) @@ -453,31 +469,35 @@ func (n *Nginx) completeConfigApply(response *NginxConfigValidationResponse) *pr } } - uploadResponse := &proto.Command_NginxConfigResponse{ - NginxConfigResponse: &proto.NginxConfigResponse{ - Action: proto.NginxConfigAction_UNKNOWN, - Status: newOKStatus("config uploaded status").CmdStatus, - ConfigData: nil, - }, - } + // Upload NGINX config only if GPRC server is configured + if n.config.IsGrpcServerConfigured() { + uploadResponse := &proto.Command_NginxConfigResponse{ + NginxConfigResponse: &proto.NginxConfigResponse{ + Action: proto.NginxConfigAction_UNKNOWN, + Status: newOKStatus("config uploaded status").CmdStatus, + ConfigData: nil, + }, + } - err := n.uploadConfig( - &proto.ConfigDescriptor{ - SystemId: n.env.GetSystemUUID(), - NginxId: response.config.GetConfigData().GetNginxId(), - }, - response.correlationId, - ) - if err != nil { - uploadResponse.NginxConfigResponse.Status = newErrStatus("Config uploaded error: " + err.Error()).CmdStatus - nginxConfigStatusMessage = fmt.Sprintf("Config uploaded error: %v", err) - log.Errorf(nginxConfigStatusMessage) - } + err := n.uploadConfig( + &proto.ConfigDescriptor{ + SystemId: n.env.GetSystemUUID(), + NginxId: response.config.GetConfigData().GetNginxId(), + }, + response.correlationId, + ) + if err != nil { + uploadResponse.NginxConfigResponse.Status = newErrStatus("Config uploaded error: " + err.Error()).CmdStatus + nginxConfigStatusMessage = fmt.Sprintf("Config uploaded error: %v", err) + log.Errorf(nginxConfigStatusMessage) + } - uploadResponseCommand := &proto.Command{Meta: grpc.NewMessageMeta(response.correlationId)} - uploadResponseCommand.Data = uploadResponse + uploadResponseCommand := &proto.Command{Meta: grpc.NewMessageMeta(response.correlationId)} + uploadResponseCommand.Data = uploadResponse + + n.messagePipeline.Process(core.NewMessage(core.CommResponse, uploadResponseCommand)) + } - n.messagePipeline.Process(core.NewMessage(core.CommResponse, uploadResponseCommand)) log.Debug("Enabling file watcher") n.messagePipeline.Process(core.NewMessage(core.FileWatcherEnabled, true)) @@ -502,6 +522,7 @@ func (n *Nginx) completeConfigApply(response *NginxConfigValidationResponse) *pr CorrelationId: response.correlationId, Status: proto.NginxConfigStatus_OK, Message: nginxConfigStatusMessage, + NginxId: response.config.GetConfigData().GetNginxId(), }, }, } @@ -510,7 +531,7 @@ func (n *Nginx) completeConfigApply(response *NginxConfigValidationResponse) *pr status := &proto.Command_NginxConfigResponse{ NginxConfigResponse: &proto.NginxConfigResponse{ - Status: newOKStatus("config apply request successfully processed").CmdStatus, + Status: newOKStatus(nginxConfigStatusMessage).CmdStatus, Action: proto.NginxConfigAction_APPLY, ConfigData: response.config.ConfigData, }, @@ -555,6 +576,7 @@ func (n *Nginx) rollbackConfigApply(response *NginxConfigValidationResponse) { CorrelationId: response.correlationId, Status: proto.NginxConfigStatus_ERROR, Message: nginxConfigStatusMessage, + NginxId: response.config.GetConfigData().GetNginxId(), }, }, } @@ -616,16 +638,7 @@ func (n *Nginx) syncAgentConfigChange() { n.isNAPEnabled = false } - n.isConfUploadEnabled = isConfUploadEnabled(conf) + n.isFeatureNginxConfigEnabled = conf.IsFeatureEnabled(agent_config.FeatureNginxConfig) n.config = conf } - -func isConfUploadEnabled(conf *config.Config) bool { - for _, feature := range conf.Features { - if feature == agent_config.FeatureNginxConfig { - return true - } - } - return false -} diff --git a/test/performance/vendor/github.com/nginx/agent/v2/test/utils/nginx.go b/test/performance/vendor/github.com/nginx/agent/v2/test/utils/nginx.go index e0105ddcc..2b614ef7a 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/test/utils/nginx.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/test/utils/nginx.go @@ -128,3 +128,44 @@ func NewMockNginxBinary() *MockNginxBinary { } var _ core.NginxBinary = NewMockNginxBinary() + +func GetDetailsNginxOssConfig() string { + return ` + user nginx; + worker_processes auto; + + error_log /usr/local/nginx/error.log notice; + pid /var/run/nginx.pid; + + events { + worker_connections 1024; + } + + + http { + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /usr/local/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + server { + listen 8080; + server_name localhost; + location /api { + stub_status; + allow 127.0.0.1; + deny all; + } + } + } + ` +} diff --git a/test/utils/nginx.go b/test/utils/nginx.go index e0105ddcc..2b614ef7a 100644 --- a/test/utils/nginx.go +++ b/test/utils/nginx.go @@ -128,3 +128,44 @@ func NewMockNginxBinary() *MockNginxBinary { } var _ core.NginxBinary = NewMockNginxBinary() + +func GetDetailsNginxOssConfig() string { + return ` + user nginx; + worker_processes auto; + + error_log /usr/local/nginx/error.log notice; + pid /var/run/nginx.pid; + + events { + worker_connections 1024; + } + + + http { + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /usr/local/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + server { + listen 8080; + server_name localhost; + location /api { + stub_status; + allow 127.0.0.1; + deny all; + } + } + } + ` +} diff --git a/vendor/github.com/nginx/agent/sdk/v2/proto/command.pb.go b/vendor/github.com/nginx/agent/sdk/v2/proto/command.pb.go index 9cd0046a2..1eb5da172 100644 --- a/vendor/github.com/nginx/agent/sdk/v2/proto/command.pb.go +++ b/vendor/github.com/nginx/agent/sdk/v2/proto/command.pb.go @@ -631,6 +631,7 @@ type NginxConfigStatus struct { CorrelationId string `protobuf:"bytes,1,opt,name=correlation_id,json=correlationId,proto3" json:"correlation_id"` Status NginxConfigStatus_Status `protobuf:"varint,2,opt,name=status,proto3,enum=f5.nginx.agent.sdk.NginxConfigStatus_Status" json:"status"` Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message"` + NginxId string `protobuf:"bytes,4,opt,name=nginx_id,json=nginxId,proto3" json:"nginx_id"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -690,6 +691,13 @@ func (m *NginxConfigStatus) GetMessage() string { return "" } +func (m *NginxConfigStatus) GetNginxId() string { + if m != nil { + return m.NginxId + } + return "" +} + type DataplaneSoftwareHealth struct { // Types that are valid to be assigned to Health: // *DataplaneSoftwareHealth_NginxHealth @@ -1253,103 +1261,103 @@ func init() { func init() { proto.RegisterFile("command.proto", fileDescriptor_213c0bb044472049) } var fileDescriptor_213c0bb044472049 = []byte{ - // 1521 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x4d, 0x6f, 0xdb, 0xc6, - 0x16, 0x25, 0x15, 0xeb, 0xeb, 0x4a, 0xb6, 0x95, 0xb1, 0x93, 0x28, 0x46, 0x60, 0x1a, 0x7c, 0x2f, - 0x2f, 0xce, 0x7b, 0x79, 0x12, 0xea, 0xa0, 0x08, 0x9a, 0xac, 0x24, 0x4b, 0x09, 0x85, 0xc4, 0x92, - 0x31, 0x89, 0x13, 0x20, 0x45, 0x21, 0x30, 0xe2, 0x48, 0x16, 0x6c, 0x91, 0x2c, 0x49, 0x39, 0x71, - 0xd0, 0x7d, 0xd1, 0xa2, 0x9b, 0x2e, 0xba, 0x28, 0xfa, 0x23, 0xfa, 0x37, 0xba, 0xcc, 0xba, 0x0b, - 0xa2, 0xc8, 0x92, 0xbb, 0x6e, 0xda, 0x45, 0x37, 0xc5, 0x7c, 0x50, 0xa2, 0x24, 0x4a, 0x76, 0xea, - 0xa2, 0x1b, 0xce, 0x70, 0x78, 0xee, 0xb9, 0x77, 0xee, 0xcc, 0x9c, 0xb9, 0x12, 0x2c, 0x77, 0xac, - 0xc1, 0x40, 0x37, 0x8d, 0x92, 0xed, 0x58, 0x9e, 0x85, 0x50, 0xf7, 0xe3, 0x92, 0xd9, 0xeb, 0x9b, - 0x6f, 0x4a, 0x7a, 0x8f, 0x98, 0x5e, 0xc9, 0x35, 0x8e, 0x36, 0xa0, 0x67, 0xf5, 0x2c, 0xfe, 0x7d, - 0x23, 0x4f, 0xe1, 0x96, 0x29, 0xde, 0x72, 0x1c, 0xc4, 0x5f, 0xe0, 0xd0, 0x72, 0xc3, 0x7e, 0x8e, - 0x73, 0x8c, 0x6c, 0xcc, 0x6e, 0xbf, 0x27, 0xde, 0x10, 0x39, 0x21, 0xa6, 0xe7, 0x96, 0x59, 0x23, - 0xc6, 0xae, 0x1b, 0x76, 0xdb, 0xb5, 0xba, 0xde, 0x6b, 0xdd, 0x21, 0x6d, 0x83, 0x78, 0x7a, 0xff, - 0xd8, 0x15, 0x9f, 0xb2, 0xa6, 0x6e, 0xf3, 0xae, 0xfa, 0x07, 0x40, 0x7a, 0x97, 0x47, 0x8b, 0xee, - 0xc3, 0xd2, 0x80, 0x78, 0x7a, 0x51, 0xde, 0x92, 0xb7, 0x73, 0x3b, 0x37, 0x4a, 0xb3, 0x61, 0x97, - 0xf6, 0x88, 0xa7, 0x1b, 0xba, 0xa7, 0x57, 0x33, 0x81, 0xaf, 0x30, 0x34, 0x66, 0x4f, 0x54, 0x87, - 0x25, 0xef, 0xd4, 0x26, 0xc5, 0xc4, 0x96, 0xbc, 0xbd, 0xb2, 0x73, 0x2b, 0xce, 0x56, 0xb8, 0x09, - 0xdb, 0x67, 0xa7, 0x36, 0xe1, 0x34, 0xd4, 0x10, 0xb3, 0x27, 0x7a, 0x09, 0xd0, 0x19, 0x18, 0x6d, - 0xd7, 0xd3, 0xbd, 0xa1, 0x5b, 0xbc, 0xc4, 0x02, 0xb9, 0xbd, 0x80, 0xec, 0x29, 0x03, 0x62, 0xe2, - 0xda, 0x96, 0xe9, 0x92, 0xea, 0x4a, 0xe0, 0x2b, 0x11, 0x02, 0x4d, 0xc2, 0xd9, 0xce, 0x40, 0x80, - 0xd0, 0x73, 0xc8, 0x33, 0x96, 0x36, 0x4f, 0x5d, 0x71, 0x89, 0xb1, 0x2b, 0x71, 0xec, 0x4d, 0xfa, - 0xbe, 0xcb, 0x60, 0xd5, 0x42, 0xe0, 0x2b, 0x13, 0x86, 0x9a, 0x84, 0xf9, 0x52, 0x70, 0x00, 0x7a, - 0x03, 0x57, 0xa2, 0x9f, 0xdb, 0x8e, 0x88, 0xa6, 0x98, 0x64, 0x0e, 0x6e, 0x9d, 0xe1, 0x60, 0x14, - 0xfc, 0xf5, 0xc0, 0x57, 0xe2, 0x99, 0x34, 0x09, 0xaf, 0x99, 0xb3, 0x16, 0xd4, 0x33, 0xa3, 0xa4, - 0x78, 0x93, 0x74, 0xbc, 0xb6, 0x43, 0x3e, 0x1f, 0x12, 0xd7, 0x2b, 0xa6, 0xe6, 0x7b, 0xae, 0xd0, - 0xde, 0x2e, 0xc7, 0x63, 0x0e, 0xe7, 0x9e, 0x63, 0x99, 0xa8, 0x67, 0x7d, 0xd6, 0x02, 0x7d, 0x01, - 0x57, 0xa7, 0xf1, 0x62, 0xd2, 0x69, 0xe6, 0x7a, 0xfb, 0x6c, 0xd7, 0x62, 0xd6, 0x1b, 0x81, 0xaf, - 0xcc, 0xe1, 0xd2, 0x24, 0xbc, 0xae, 0xc7, 0xd8, 0x20, 0x0f, 0xd6, 0x47, 0x16, 0x3c, 0x4f, 0x7c, - 0xda, 0x19, 0xe6, 0xfb, 0x3f, 0x8b, 0x7c, 0xb3, 0xf4, 0xf1, 0x59, 0x17, 0x03, 0x5f, 0x89, 0xe5, - 0xd1, 0x24, 0x8c, 0xf4, 0x19, 0x3c, 0xdd, 0x3f, 0x51, 0x74, 0x31, 0x3b, 0x7f, 0xff, 0x44, 0xbc, - 0xf1, 0xfd, 0x13, 0x35, 0xa4, 0xfb, 0x27, 0x42, 0x8f, 0xba, 0x50, 0xa0, 0x47, 0xca, 0x3e, 0xd6, - 0x4d, 0x12, 0xee, 0xfc, 0x1c, 0xe3, 0xfe, 0x57, 0x1c, 0x77, 0x2d, 0xc4, 0xf2, 0x6d, 0x5d, 0x5d, - 0x0f, 0x7c, 0x65, 0x86, 0x40, 0x93, 0xf0, 0xaa, 0x31, 0x09, 0x44, 0x9f, 0x41, 0x9e, 0xe9, 0x43, - 0xdb, 0x21, 0xb6, 0xe5, 0x78, 0xc5, 0xfc, 0xfc, 0x6c, 0x71, 0x39, 0x29, 0xd5, 0x69, 0x83, 0x19, - 0x9a, 0x4f, 0x23, 0x6a, 0x4f, 0xa7, 0x41, 0xc6, 0x00, 0xf4, 0x8d, 0x0c, 0x1b, 0x91, 0x30, 0xa6, - 0x94, 0xa7, 0xb8, 0xcc, 0xbc, 0xdd, 0x59, 0x3c, 0x23, 0x61, 0x54, 0xe3, 0x36, 0xd5, 0xcd, 0xc0, - 0x57, 0x16, 0x70, 0x6a, 0x12, 0x2e, 0x1a, 0x73, 0x6c, 0x27, 0xb3, 0x3a, 0xb4, 0x0d, 0xdd, 0x23, - 0xc5, 0x95, 0x73, 0x64, 0xf5, 0x80, 0x41, 0xa7, 0xb3, 0xca, 0x09, 0x26, 0xb2, 0xca, 0x81, 0xea, - 0x5d, 0xc8, 0x45, 0x04, 0x0d, 0x01, 0xa4, 0x9a, 0x2d, 0xbc, 0x57, 0x79, 0x52, 0x90, 0x50, 0x1e, - 0x32, 0xb5, 0xd6, 0x8b, 0xe6, 0x93, 0x56, 0xa5, 0x56, 0x90, 0xe9, 0x97, 0x83, 0x7d, 0xd6, 0x4f, - 0x54, 0x53, 0xb0, 0x44, 0x79, 0xd4, 0xef, 0x2e, 0xc1, 0x95, 0x58, 0x25, 0x43, 0x9f, 0x42, 0x4a, - 0x6c, 0x05, 0x99, 0x29, 0xea, 0xbd, 0x73, 0x8b, 0xe0, 0xe4, 0x68, 0x15, 0x02, 0x5f, 0x11, 0x54, - 0x58, 0xb4, 0xa8, 0x0f, 0x40, 0x1c, 0xc7, 0x72, 0xda, 0x1d, 0xcb, 0x08, 0x25, 0xfb, 0xfe, 0x07, - 0x3b, 0xa8, 0x53, 0x8a, 0x5d, 0xcb, 0x10, 0xb2, 0x3b, 0x66, 0xc4, 0x59, 0x12, 0x7e, 0x42, 0x37, - 0x21, 0x3d, 0x20, 0xae, 0xab, 0xf7, 0x08, 0x53, 0xf3, 0x6c, 0x35, 0x17, 0xf8, 0x4a, 0x38, 0x84, - 0xc3, 0x0e, 0x52, 0x20, 0xc9, 0x6c, 0x98, 0x28, 0x67, 0xab, 0xd9, 0xc0, 0x57, 0xf8, 0x00, 0xe6, - 0x8d, 0xfa, 0x00, 0x96, 0x27, 0x82, 0x41, 0xab, 0x90, 0xdb, 0xdd, 0xab, 0xb5, 0x0f, 0x9a, 0x8f, - 0x9b, 0xad, 0x17, 0xcd, 0x82, 0x44, 0xf3, 0x4b, 0x07, 0x5a, 0x8f, 0x0b, 0x32, 0x5a, 0x86, 0x2c, - 0xed, 0xd7, 0x31, 0x6e, 0xe1, 0x42, 0x42, 0x2d, 0x43, 0x61, 0x3a, 0x66, 0x0a, 0xaf, 0x63, 0x4c, - 0xe1, 0x12, 0xe5, 0xa2, 0xfd, 0x90, 0x4b, 0x56, 0x7f, 0x48, 0xc2, 0xea, 0xd4, 0x39, 0x43, 0xff, - 0x85, 0xac, 0x7b, 0xea, 0x7a, 0x64, 0xd0, 0xee, 0x1b, 0x6c, 0x51, 0xb2, 0xd5, 0xe5, 0xc0, 0x57, - 0xc6, 0x83, 0x38, 0xc3, 0xbb, 0x0d, 0x03, 0x3d, 0x82, 0x74, 0xb8, 0xef, 0x13, 0x5b, 0x97, 0xb6, - 0x73, 0x3b, 0x5b, 0x73, 0x2f, 0x81, 0x70, 0xaf, 0xb3, 0xbc, 0x08, 0x23, 0x1c, 0x76, 0xe8, 0x95, - 0x4c, 0x2b, 0x00, 0x71, 0x13, 0xc6, 0x5e, 0xc9, 0x9a, 0xe5, 0x7a, 0x0d, 0xb3, 0x6b, 0xf1, 0xbb, - 0x94, 0xa2, 0x31, 0x7b, 0xa2, 0x87, 0x90, 0x3e, 0x24, 0xfa, 0xb1, 0x77, 0xe8, 0x16, 0x93, 0x2c, - 0x88, 0xf9, 0x57, 0x9d, 0xc6, 0x70, 0x3c, 0x06, 0x61, 0x83, 0xc3, 0x0e, 0xfa, 0x7a, 0xf1, 0xc1, - 0x4e, 0x31, 0xee, 0xbf, 0xf5, 0x60, 0x2f, 0x38, 0xd6, 0x5f, 0xc5, 0x07, 0x13, 0x4e, 0x34, 0xcd, - 0x82, 0xf9, 0xdf, 0xb9, 0x82, 0x11, 0x93, 0x9e, 0x17, 0x4b, 0x98, 0x87, 0xd9, 0x58, 0x34, 0x91, - 0x98, 0x93, 0xf0, 0xfa, 0xd5, 0x3b, 0x5e, 0xff, 0xa4, 0xef, 0x9d, 0x86, 0xea, 0x9d, 0x61, 0x51, - 0xcc, 0xbf, 0x7e, 0x2b, 0x02, 0x2f, 0x8e, 0x68, 0xe4, 0xfa, 0x9d, 0x62, 0x12, 0x97, 0xef, 0x24, - 0x5e, 0xfd, 0x56, 0x86, 0xb5, 0x18, 0x1e, 0x64, 0xc3, 0xda, 0x44, 0xf9, 0x10, 0x11, 0x90, 0xdc, - 0xce, 0xcd, 0x33, 0xca, 0x10, 0x11, 0xcb, 0xb5, 0xc0, 0x57, 0xe2, 0x58, 0x34, 0x09, 0x5f, 0x36, - 0x67, 0xd0, 0x19, 0x48, 0x89, 0x98, 0x7e, 0x95, 0xe1, 0xf2, 0x0c, 0x1b, 0xfa, 0x04, 0x56, 0x3a, - 0x96, 0xe3, 0x90, 0x63, 0xdd, 0xeb, 0x5b, 0xe6, 0xf8, 0xe0, 0xa0, 0xc0, 0x57, 0xa6, 0xbe, 0xe0, - 0xe5, 0xc8, 0x7b, 0xc3, 0x40, 0xfb, 0x23, 0x01, 0xe4, 0xfa, 0x74, 0xe7, 0x5c, 0xf1, 0x97, 0x16, - 0xa8, 0xde, 0xf9, 0xa4, 0x48, 0xdd, 0x0e, 0xe7, 0x84, 0x72, 0x90, 0xde, 0xaf, 0x37, 0x6b, 0x8d, - 0xe6, 0xa3, 0x82, 0x84, 0x52, 0x90, 0x60, 0xd2, 0x92, 0x85, 0x64, 0x28, 0x2b, 0xbf, 0xcb, 0x70, - 0x6d, 0xce, 0xae, 0x1a, 0x17, 0x9b, 0x7c, 0x1b, 0x89, 0x45, 0x38, 0xf3, 0x04, 0x46, 0x8a, 0x4d, - 0x6e, 0x38, 0x2a, 0x36, 0x05, 0xef, 0x5b, 0xb8, 0xaa, 0xdb, 0x76, 0x9b, 0x16, 0xef, 0xb4, 0x54, - 0x7a, 0xad, 0x77, 0x43, 0x0f, 0x89, 0x05, 0x35, 0x9f, 0x6d, 0xef, 0x73, 0x83, 0x17, 0x95, 0x87, - 0xc2, 0x13, 0xaf, 0xbb, 0x62, 0xa9, 0x58, 0xd1, 0x37, 0x36, 0xd1, 0xbb, 0xc2, 0x24, 0x03, 0x29, - 0x0e, 0x50, 0x7f, 0x96, 0x23, 0xfa, 0xc8, 0x2f, 0xc2, 0x91, 0x54, 0xc9, 0x7f, 0x41, 0xaa, 0xce, - 0x90, 0x98, 0xc4, 0x3f, 0x29, 0x31, 0xea, 0x1e, 0xac, 0xd6, 0xac, 0xd7, 0xe6, 0xb1, 0xa5, 0x1b, - 0x61, 0xe9, 0x77, 0x81, 0x5f, 0x46, 0xea, 0x97, 0x09, 0x58, 0x8b, 0x29, 0xf7, 0xd1, 0xde, 0xc4, - 0x0d, 0xff, 0x41, 0x3f, 0x73, 0xe2, 0x76, 0x77, 0x03, 0x52, 0x54, 0x3c, 0x2c, 0x53, 0x9c, 0x97, - 0xb3, 0xce, 0x7b, 0x85, 0x81, 0x39, 0x15, 0x37, 0xc4, 0xa2, 0x45, 0xcf, 0x21, 0x27, 0xce, 0x3e, - 0x9d, 0x90, 0xb8, 0x7b, 0xfe, 0x1d, 0x1f, 0x1e, 0x85, 0xd5, 0x88, 0xdb, 0x71, 0xfa, 0xb6, 0x67, - 0x39, 0xd5, 0xd5, 0xc0, 0x57, 0xa2, 0xc6, 0x18, 0xf8, 0x0b, 0x5d, 0x26, 0xf5, 0x37, 0x19, 0xf2, - 0x07, 0x36, 0xcd, 0xab, 0x38, 0x60, 0x17, 0xf9, 0xc1, 0xf9, 0x74, 0x4a, 0x1f, 0xca, 0x71, 0xd6, - 0x51, 0x6f, 0xa5, 0x67, 0x8e, 0x6e, 0xba, 0x5d, 0xe2, 0x2c, 0x90, 0x08, 0x15, 0x52, 0x0e, 0xd1, - 0x5d, 0xcb, 0x14, 0x0a, 0xc1, 0x30, 0x7c, 0x04, 0x8b, 0x56, 0xfd, 0x08, 0x56, 0x26, 0x99, 0xa8, - 0x4e, 0x8c, 0xcb, 0x90, 0x50, 0x27, 0x00, 0x52, 0x0f, 0x2b, 0x8d, 0x27, 0xf5, 0x5a, 0x21, 0xa1, - 0xfe, 0x28, 0x43, 0x96, 0x66, 0x60, 0xf7, 0x70, 0x68, 0x1e, 0xa1, 0x16, 0x3b, 0x46, 0x06, 0x71, - 0x16, 0x2e, 0x3c, 0x85, 0x12, 0x03, 0x13, 0xd7, 0x1a, 0x3a, 0x1d, 0xaa, 0x2a, 0x06, 0x71, 0x78, - 0x3c, 0xdc, 0x58, 0x93, 0xb0, 0xe8, 0x21, 0x8d, 0x57, 0x93, 0x42, 0x01, 0xb6, 0xcf, 0x41, 0xc7, - 0x5e, 0x79, 0x4a, 0xa9, 0xa5, 0x26, 0x61, 0xd6, 0x56, 0xd3, 0x90, 0xec, 0xd0, 0x4f, 0xea, 0x3b, - 0x19, 0xae, 0xc4, 0x86, 0x70, 0xa1, 0x35, 0x53, 0x21, 0xc5, 0xe8, 0xf9, 0x9a, 0x25, 0xf9, 0x74, - 0xf8, 0x08, 0x16, 0x2d, 0xda, 0x86, 0x4c, 0xe7, 0x90, 0x74, 0x8e, 0xdc, 0xe1, 0x40, 0x2c, 0x42, - 0x3e, 0xf0, 0x95, 0xd1, 0x18, 0x1e, 0xf5, 0xd0, 0xff, 0x01, 0x98, 0x4d, 0xdb, 0xed, 0xbf, 0x25, - 0xac, 0x70, 0x4c, 0x8a, 0x3f, 0x00, 0x46, 0xa3, 0x38, 0xcb, 0xfa, 0x4f, 0xfb, 0x6f, 0x89, 0xfa, - 0xbd, 0x0c, 0xeb, 0x71, 0x69, 0xb8, 0xd0, 0x8c, 0x6e, 0xd1, 0x68, 0xa9, 0xb7, 0xbe, 0x21, 0xe6, - 0x24, 0xa2, 0xe5, 0x63, 0x38, 0xcd, 0x7a, 0x0d, 0x03, 0xdd, 0x10, 0x6b, 0x44, 0xa7, 0x94, 0x1f, - 0x67, 0x5e, 0xe4, 0xfd, 0xde, 0x4f, 0xef, 0x37, 0xe5, 0x77, 0xef, 0x37, 0xe5, 0x5f, 0xde, 0x6f, - 0xca, 0x2f, 0x6f, 0xf7, 0xfa, 0xde, 0xe1, 0xf0, 0x55, 0xa9, 0x63, 0x0d, 0xca, 0x2c, 0x92, 0x32, - 0x8b, 0xa4, 0xec, 0x1a, 0x47, 0xe5, 0x93, 0x9d, 0x32, 0xfb, 0xe3, 0xe6, 0x01, 0x7b, 0xbe, 0x4a, - 0xb1, 0xe6, 0xee, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc3, 0xee, 0xd6, 0x35, 0x72, 0x12, 0x00, - 0x00, + // 1535 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xcb, 0x6e, 0xdb, 0x46, + 0x17, 0x26, 0x15, 0xeb, 0x76, 0x24, 0xdb, 0xca, 0xd8, 0x49, 0x14, 0x23, 0x30, 0x0d, 0xfe, 0x7f, + 0x6a, 0xa7, 0x4d, 0x25, 0xd4, 0x41, 0x11, 0x34, 0x59, 0x59, 0x96, 0x13, 0x0a, 0x89, 0x65, 0x63, + 0x12, 0x27, 0x40, 0x8a, 0x42, 0x60, 0xc4, 0x91, 0x4c, 0xd8, 0x22, 0x59, 0x92, 0x72, 0xe2, 0xa0, + 0xfb, 0xa2, 0x45, 0x37, 0x5d, 0x74, 0xd1, 0xf6, 0x21, 0xfa, 0x1a, 0x5d, 0x66, 0xdd, 0x05, 0x51, + 0x64, 0xc9, 0x07, 0x68, 0x17, 0xdd, 0x14, 0x73, 0xa1, 0x44, 0x49, 0x94, 0xec, 0xd4, 0x45, 0x37, + 0x9a, 0xe1, 0xf0, 0x3b, 0xdf, 0xb9, 0xcc, 0xcc, 0x37, 0x43, 0xc1, 0x7c, 0xdb, 0xee, 0xf5, 0x74, + 0xcb, 0xa8, 0x38, 0xae, 0xed, 0xdb, 0x08, 0x75, 0x3e, 0xad, 0x58, 0x5d, 0xd3, 0x7a, 0x5d, 0xd1, + 0xbb, 0xc4, 0xf2, 0x2b, 0x9e, 0x71, 0xb4, 0x02, 0x5d, 0xbb, 0x6b, 0xf3, 0xf7, 0x2b, 0x45, 0x0a, + 0xb7, 0x2d, 0xf1, 0x54, 0xe0, 0x20, 0xfe, 0x00, 0x87, 0xb6, 0x17, 0xf5, 0x0b, 0x9c, 0x63, 0x60, + 0x63, 0x75, 0xcc, 0xae, 0x78, 0x42, 0xe4, 0x84, 0x58, 0xbe, 0x57, 0x65, 0x8d, 0x18, 0xbb, 0x6e, + 0x38, 0x2d, 0xcf, 0xee, 0xf8, 0xaf, 0x74, 0x97, 0xb4, 0x0c, 0xe2, 0xeb, 0xe6, 0xb1, 0x27, 0x5e, + 0xe5, 0x2d, 0xdd, 0xe1, 0x5d, 0xf5, 0x2f, 0x80, 0xec, 0x36, 0x8f, 0x16, 0xdd, 0x83, 0xb9, 0x1e, + 0xf1, 0xf5, 0xb2, 0xbc, 0x26, 0x6f, 0x14, 0x36, 0x6f, 0x54, 0x26, 0xc3, 0xae, 0xec, 0x12, 0x5f, + 0x37, 0x74, 0x5f, 0xaf, 0xe5, 0xc2, 0x40, 0x61, 0x68, 0xcc, 0x7e, 0xd1, 0x0e, 0xcc, 0xf9, 0xa7, + 0x0e, 0x29, 0xa7, 0xd6, 0xe4, 0x8d, 0x85, 0xcd, 0xf5, 0x24, 0x5b, 0xe1, 0x26, 0x6a, 0x9f, 0x9e, + 0x3a, 0x84, 0xd3, 0x50, 0x43, 0xcc, 0x7e, 0xd1, 0x0b, 0x80, 0x76, 0xcf, 0x68, 0x79, 0xbe, 0xee, + 0xf7, 0xbd, 0xf2, 0x25, 0x16, 0xc8, 0xad, 0x19, 0x64, 0x4f, 0x18, 0x10, 0x13, 0xcf, 0xb1, 0x2d, + 0x8f, 0xd4, 0x16, 0xc2, 0x40, 0x89, 0x11, 0x68, 0x12, 0xce, 0xb7, 0x7b, 0x02, 0x84, 0x9e, 0x41, + 0x91, 0xb1, 0xb4, 0x78, 0xe9, 0xca, 0x73, 0x8c, 0x5d, 0x49, 0x62, 0x6f, 0xd2, 0xe7, 0x6d, 0x06, + 0xab, 0x95, 0xc2, 0x40, 0x19, 0x31, 0xd4, 0x24, 0xcc, 0xa7, 0x82, 0x03, 0xd0, 0x6b, 0xb8, 0x12, + 0x7f, 0xdd, 0x72, 0x45, 0x34, 0xe5, 0x34, 0x73, 0xb0, 0x7e, 0x86, 0x83, 0x41, 0xf0, 0xd7, 0xc3, + 0x40, 0x49, 0x66, 0xd2, 0x24, 0xbc, 0x64, 0x4d, 0x5a, 0x50, 0xcf, 0x8c, 0x92, 0xe2, 0x2d, 0xd2, + 0xf6, 0x5b, 0x2e, 0xf9, 0xb2, 0x4f, 0x3c, 0xbf, 0x9c, 0x99, 0xee, 0x79, 0x8b, 0xf6, 0xb6, 0x39, + 0x1e, 0x73, 0x38, 0xf7, 0x9c, 0xc8, 0x44, 0x3d, 0xeb, 0x93, 0x16, 0xe8, 0x2b, 0xb8, 0x3a, 0x8e, + 0x17, 0x49, 0x67, 0x99, 0xeb, 0x8d, 0xb3, 0x5d, 0x8b, 0xac, 0x57, 0xc2, 0x40, 0x99, 0xc2, 0xa5, + 0x49, 0x78, 0x59, 0x4f, 0xb0, 0x41, 0x3e, 0x2c, 0x0f, 0x2c, 0x78, 0x9d, 0x78, 0xda, 0x39, 0xe6, + 0xfb, 0x83, 0x59, 0xbe, 0x59, 0xf9, 0x78, 0xd6, 0xe5, 0x30, 0x50, 0x12, 0x79, 0x34, 0x09, 0x23, + 0x7d, 0x02, 0x4f, 0xd7, 0x4f, 0x1c, 0x5d, 0xce, 0x4f, 0x5f, 0x3f, 0x31, 0x6f, 0x7c, 0xfd, 0xc4, + 0x0d, 0xe9, 0xfa, 0x89, 0xd1, 0xa3, 0x0e, 0x94, 0xe8, 0x96, 0x72, 0x8e, 0x75, 0x8b, 0x44, 0x2b, + 0xbf, 0xc0, 0xb8, 0xff, 0x97, 0xc4, 0x5d, 0x8f, 0xb0, 0x7c, 0x59, 0xd7, 0x96, 0xc3, 0x40, 0x99, + 0x20, 0xd0, 0x24, 0xbc, 0x68, 0x8c, 0x02, 0xd1, 0x17, 0x50, 0x64, 0xfa, 0xd0, 0x72, 0x89, 0x63, + 0xbb, 0x7e, 0xb9, 0x38, 0xbd, 0x5a, 0x5c, 0x4e, 0x2a, 0x3b, 0xb4, 0xc1, 0x0c, 0xcd, 0xd3, 0x88, + 0xdb, 0xd3, 0x34, 0xc8, 0x10, 0x80, 0xbe, 0x93, 0x61, 0x25, 0x16, 0xc6, 0x98, 0xf2, 0x94, 0xe7, + 0x99, 0xb7, 0xdb, 0xb3, 0x33, 0x12, 0x46, 0x75, 0x6e, 0x53, 0x5b, 0x0d, 0x03, 0x65, 0x06, 0xa7, + 0x26, 0xe1, 0xb2, 0x31, 0xc5, 0x76, 0xb4, 0xaa, 0x7d, 0xc7, 0xd0, 0x7d, 0x52, 0x5e, 0x38, 0x47, + 0x55, 0x0f, 0x18, 0x74, 0xbc, 0xaa, 0x9c, 0x60, 0xa4, 0xaa, 0x1c, 0xa8, 0xde, 0x81, 0x42, 0x4c, + 0xd0, 0x10, 0x40, 0xa6, 0xb9, 0x87, 0x77, 0xb7, 0x1e, 0x97, 0x24, 0x54, 0x84, 0x5c, 0x7d, 0xef, + 0x79, 0xf3, 0xf1, 0xde, 0x56, 0xbd, 0x24, 0xd3, 0x37, 0x07, 0xfb, 0xac, 0x9f, 0xaa, 0x65, 0x60, + 0x8e, 0xf2, 0xa8, 0x3f, 0x5c, 0x82, 0x2b, 0x89, 0x4a, 0x86, 0x3e, 0x87, 0x8c, 0x58, 0x0a, 0x32, + 0x53, 0xd4, 0xbb, 0xe7, 0x16, 0xc1, 0xd1, 0xd1, 0x1a, 0x84, 0x81, 0x22, 0xa8, 0xb0, 0x68, 0x91, + 0x09, 0x40, 0x5c, 0xd7, 0x76, 0x5b, 0x6d, 0xdb, 0x88, 0x24, 0xfb, 0xde, 0x7b, 0x3b, 0xd8, 0xa1, + 0x14, 0xdb, 0xb6, 0x21, 0x64, 0x77, 0xc8, 0x88, 0xf3, 0x24, 0x7a, 0x85, 0x6e, 0x42, 0xb6, 0x47, + 0x3c, 0x4f, 0xef, 0x12, 0xa6, 0xe6, 0xf9, 0x5a, 0x21, 0x0c, 0x94, 0x68, 0x08, 0x47, 0x1d, 0xa4, + 0x40, 0x9a, 0xd9, 0x30, 0x51, 0xce, 0xd7, 0xf2, 0x61, 0xa0, 0xf0, 0x01, 0xcc, 0x1b, 0xf5, 0x3e, + 0xcc, 0x8f, 0x04, 0x83, 0x16, 0xa1, 0xb0, 0xbd, 0x5b, 0x6f, 0x1d, 0x34, 0x1f, 0x35, 0xf7, 0x9e, + 0x37, 0x4b, 0x12, 0xad, 0x2f, 0x1d, 0xd8, 0x7b, 0x54, 0x92, 0xd1, 0x3c, 0xe4, 0x69, 0x7f, 0x07, + 0xe3, 0x3d, 0x5c, 0x4a, 0xa9, 0x55, 0x28, 0x8d, 0xc7, 0x4c, 0xe1, 0x3b, 0x18, 0x53, 0xb8, 0x44, + 0xb9, 0x68, 0x3f, 0xe2, 0x92, 0xd5, 0x9f, 0xd3, 0xb0, 0x38, 0xb6, 0xcf, 0xd0, 0x87, 0x90, 0xf7, + 0x4e, 0x3d, 0x9f, 0xf4, 0x5a, 0xa6, 0xc1, 0x26, 0x25, 0x5f, 0x9b, 0x0f, 0x03, 0x65, 0x38, 0x88, + 0x73, 0xbc, 0xdb, 0x30, 0xd0, 0x43, 0xc8, 0x46, 0xeb, 0x3e, 0xb5, 0x76, 0x69, 0xa3, 0xb0, 0xb9, + 0x36, 0xf5, 0x10, 0x88, 0xd6, 0x3a, 0xab, 0x8b, 0x30, 0xc2, 0x51, 0x87, 0x1e, 0xc9, 0xf4, 0x06, + 0x20, 0x4e, 0xc2, 0xc4, 0x23, 0x59, 0xb3, 0x3d, 0xbf, 0x61, 0x75, 0x6c, 0x7e, 0x96, 0x52, 0x34, + 0x66, 0xbf, 0xe8, 0x01, 0x64, 0x0f, 0x89, 0x7e, 0xec, 0x1f, 0x7a, 0xe5, 0x34, 0x0b, 0x62, 0xfa, + 0x51, 0xa7, 0x31, 0x1c, 0x8f, 0x41, 0xd8, 0xe0, 0xa8, 0x83, 0xbe, 0x9d, 0xbd, 0xb1, 0x33, 0x8c, + 0xfb, 0x5f, 0xdd, 0xd8, 0x33, 0xb6, 0xf5, 0x37, 0xc9, 0xc1, 0x44, 0x89, 0x66, 0x59, 0x30, 0x1f, + 0x9d, 0x2b, 0x18, 0x91, 0xf4, 0xb4, 0x58, 0xa2, 0x3a, 0x4c, 0xc6, 0xa2, 0x89, 0xc2, 0x9c, 0x44, + 0xc7, 0xaf, 0xde, 0xf6, 0xcd, 0x13, 0xd3, 0x3f, 0x8d, 0xd4, 0x3b, 0xc7, 0xa2, 0x98, 0x7e, 0xfc, + 0x6e, 0x09, 0xbc, 0xd8, 0xa2, 0xb1, 0xe3, 0x77, 0x8c, 0x49, 0x1c, 0xbe, 0xa3, 0x78, 0xf5, 0x7b, + 0x19, 0x96, 0x12, 0x78, 0x90, 0x03, 0x4b, 0x23, 0xd7, 0x87, 0x98, 0x80, 0x14, 0x36, 0x6f, 0x9e, + 0x71, 0x0d, 0x11, 0xb1, 0x5c, 0x0b, 0x03, 0x25, 0x89, 0x45, 0x93, 0xf0, 0x65, 0x6b, 0x02, 0x9d, + 0x83, 0x8c, 0x88, 0xe9, 0xa7, 0x14, 0x5c, 0x9e, 0x60, 0x43, 0x9f, 0xc1, 0x42, 0xdb, 0x76, 0x5d, + 0x72, 0xac, 0xfb, 0xa6, 0x6d, 0x0d, 0x37, 0x0e, 0x0a, 0x03, 0x65, 0xec, 0x0d, 0x9e, 0x8f, 0x3d, + 0x37, 0x0c, 0xb4, 0x3f, 0x10, 0x40, 0xae, 0x4f, 0xb7, 0xcf, 0x15, 0x7f, 0x65, 0x86, 0xea, 0x9d, + 0x53, 0x8a, 0xd6, 0x21, 0xc7, 0xf3, 0x37, 0x0d, 0xa1, 0x46, 0xc5, 0x30, 0x50, 0x06, 0x63, 0x38, + 0xcb, 0x7a, 0x0d, 0x43, 0xdd, 0x88, 0x92, 0x47, 0x05, 0xc8, 0xee, 0xef, 0x34, 0xeb, 0x8d, 0xe6, + 0xc3, 0x92, 0x84, 0x32, 0x90, 0x62, 0x1a, 0x94, 0x87, 0x74, 0xa4, 0x3f, 0x7f, 0xca, 0x70, 0x6d, + 0xca, 0xf2, 0x1b, 0xde, 0x4a, 0xf9, 0x7a, 0x13, 0xb3, 0x75, 0xe6, 0x56, 0x8d, 0xdd, 0x4a, 0xb9, + 0xe1, 0xe0, 0x56, 0x2a, 0x78, 0xdf, 0xc0, 0x55, 0xdd, 0x71, 0x5a, 0xf4, 0x96, 0x4f, 0xef, 0x54, + 0xaf, 0xf4, 0x4e, 0xe4, 0x21, 0x35, 0xe3, 0x72, 0xe8, 0x38, 0xfb, 0xdc, 0xe0, 0xf9, 0xd6, 0x03, + 0xe1, 0x89, 0x5f, 0xd0, 0x12, 0xa9, 0xd8, 0xed, 0x70, 0x68, 0xa2, 0x77, 0x84, 0x49, 0x0e, 0x32, + 0x1c, 0xa0, 0xfe, 0x26, 0xc7, 0x84, 0x94, 0x9f, 0x98, 0x03, 0x4d, 0x93, 0xff, 0x81, 0xa6, 0x9d, + 0xa1, 0x45, 0xa9, 0xff, 0x52, 0x8b, 0xd4, 0x5d, 0x58, 0xac, 0xdb, 0xaf, 0xac, 0x63, 0x5b, 0x37, + 0xa2, 0x3b, 0xe2, 0x05, 0x3e, 0xa1, 0xd4, 0xaf, 0x53, 0xb0, 0x94, 0xf0, 0x5d, 0x80, 0x76, 0x47, + 0xae, 0x02, 0xef, 0xf5, 0x3d, 0x94, 0xb4, 0x0d, 0x1a, 0x90, 0xa1, 0x2a, 0x63, 0x5b, 0x62, 0x63, + 0x9d, 0x25, 0x0c, 0x5b, 0x0c, 0xcc, 0xa9, 0xb8, 0x21, 0x16, 0x2d, 0x7a, 0x06, 0x05, 0x21, 0x12, + 0x34, 0x21, 0x71, 0x48, 0xfd, 0x3f, 0x39, 0x3c, 0x0a, 0xab, 0x13, 0xaf, 0xed, 0x9a, 0x8e, 0x6f, + 0xbb, 0xb5, 0xc5, 0x30, 0x50, 0xe2, 0xc6, 0x18, 0xf8, 0x03, 0x9d, 0x26, 0xf5, 0x0f, 0x19, 0x8a, + 0x07, 0x0e, 0xad, 0xab, 0xd8, 0x60, 0x17, 0xf9, 0x32, 0x7d, 0x32, 0x26, 0x24, 0xd5, 0x24, 0xeb, + 0xb8, 0xb7, 0xca, 0x53, 0x57, 0xb7, 0xbc, 0x0e, 0x71, 0x67, 0x68, 0x89, 0x0a, 0x19, 0x97, 0xe8, + 0x9e, 0x6d, 0x09, 0x29, 0x61, 0x18, 0x3e, 0x82, 0x45, 0xab, 0x7e, 0x02, 0x0b, 0xa3, 0x4c, 0x54, + 0x27, 0x86, 0xf7, 0x95, 0x48, 0x27, 0x00, 0x32, 0x0f, 0xb6, 0x1a, 0x8f, 0x77, 0xea, 0xa5, 0x94, + 0xfa, 0x8b, 0x0c, 0x79, 0x5a, 0x81, 0xed, 0xc3, 0xbe, 0x75, 0x84, 0xf6, 0xd8, 0x36, 0x32, 0x88, + 0x3b, 0x73, 0xe2, 0x29, 0x94, 0x18, 0x98, 0x78, 0x76, 0xdf, 0x6d, 0x53, 0x55, 0x31, 0x88, 0xcb, + 0xe3, 0xe1, 0xc6, 0x9a, 0x84, 0x45, 0x0f, 0x69, 0xfc, 0xda, 0x29, 0x14, 0x60, 0xe3, 0x1c, 0x74, + 0xec, 0x91, 0x97, 0x94, 0x5a, 0x6a, 0x12, 0x66, 0x6d, 0x2d, 0x0b, 0xe9, 0x36, 0x7d, 0xa5, 0xbe, + 0x95, 0xe1, 0x4a, 0x62, 0x08, 0x17, 0x9a, 0x33, 0x15, 0x32, 0x8c, 0x9e, 0xcf, 0x59, 0x9a, 0xa7, + 0xc3, 0x47, 0xb0, 0x68, 0xd1, 0x06, 0xe4, 0xda, 0x87, 0xa4, 0x7d, 0xe4, 0xf5, 0x7b, 0x62, 0x12, + 0x98, 0x4e, 0x47, 0x63, 0x78, 0xd0, 0x43, 0x1f, 0x03, 0x30, 0x9b, 0x96, 0x67, 0xbe, 0x21, 0x4c, + 0xd3, 0xd3, 0xe2, 0x9f, 0x82, 0xc1, 0x28, 0xce, 0xb3, 0xfe, 0x13, 0xf3, 0x0d, 0x51, 0x7f, 0x94, + 0x61, 0x39, 0xa9, 0x0c, 0x17, 0xca, 0x68, 0x9d, 0x46, 0x4b, 0xbd, 0x99, 0x86, 0xc8, 0x49, 0x44, + 0xcb, 0xc7, 0x70, 0x96, 0xf5, 0x1a, 0x06, 0xba, 0x21, 0xe6, 0x88, 0xa6, 0x54, 0x1c, 0x56, 0x5e, + 0xd4, 0xfd, 0xee, 0xaf, 0xef, 0x56, 0xe5, 0xb7, 0xef, 0x56, 0xe5, 0xdf, 0xdf, 0xad, 0xca, 0x2f, + 0x6e, 0x75, 0x4d, 0xff, 0xb0, 0xff, 0xb2, 0xd2, 0xb6, 0x7b, 0x55, 0x16, 0x49, 0x95, 0x45, 0x52, + 0xf5, 0x8c, 0xa3, 0xea, 0xc9, 0x66, 0x95, 0xfd, 0xc3, 0x73, 0x9f, 0xfd, 0xbe, 0xcc, 0xb0, 0xe6, + 0xce, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc1, 0x1f, 0x57, 0x17, 0x9b, 0x12, 0x00, 0x00, } func (m *Command) Marshal() (dAtA []byte, err error) { @@ -1884,6 +1892,13 @@ func (m *NginxConfigStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.NginxId) > 0 { + i -= len(m.NginxId) + copy(dAtA[i:], m.NginxId) + i = encodeVarintCommand(dAtA, i, uint64(len(m.NginxId))) + i-- + dAtA[i] = 0x22 + } if len(m.Message) > 0 { i -= len(m.Message) copy(dAtA[i:], m.Message) @@ -2653,6 +2668,10 @@ func (m *NginxConfigStatus) Size() (n int) { if l > 0 { n += 1 + l + sovCommand(uint64(l)) } + l = len(m.NginxId) + if l > 0 { + n += 1 + l + sovCommand(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -4007,6 +4026,38 @@ func (m *NginxConfigStatus) Unmarshal(dAtA []byte) error { } m.Message = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NginxId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommand + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommand + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommand + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NginxId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommand(dAtA[iNdEx:]) diff --git a/vendor/github.com/nginx/agent/sdk/v2/proto/command.proto b/vendor/github.com/nginx/agent/sdk/v2/proto/command.proto index 4ae215aa5..feb738c3c 100644 --- a/vendor/github.com/nginx/agent/sdk/v2/proto/command.proto +++ b/vendor/github.com/nginx/agent/sdk/v2/proto/command.proto @@ -103,6 +103,7 @@ message NginxConfigStatus { string correlation_id = 1 [(gogoproto.jsontag) = "correlation_id" ]; Status status = 2 [(gogoproto.jsontag) = "status" ]; string message = 3 [(gogoproto.jsontag) = "message" ]; + string nginx_id = 4 [(gogoproto.jsontag) = "nginx_id" ]; enum Status { PENDING = 0;