diff --git a/sdk/agent/config/config_helpers.go b/sdk/agent/config/config_helpers.go new file mode 100644 index 000000000..62e6492b5 --- /dev/null +++ b/sdk/agent/config/config_helpers.go @@ -0,0 +1,35 @@ +package config + +const ( + KeyDelimiter = "_" + + // viper keys used in config + FeaturesKey = "features" + FeatureRegistration = FeaturesKey + KeyDelimiter + "registration" + FeatureNginxConfig = FeaturesKey + KeyDelimiter + "nginx-config" + FeatureNginxConfigAsync = FeaturesKey + KeyDelimiter + "nginx-config-async" + FeatureNginxSSLConfig = FeaturesKey + KeyDelimiter + "nginx-ssl-config" + FeatureNginxCounting = FeaturesKey + KeyDelimiter + "nginx-counting" + FeatureMetrics = FeaturesKey + KeyDelimiter + "metrics" + FeatureMetricsThrottle = FeaturesKey + KeyDelimiter + "metrics-throttle" + FeatureDataPlaneStatus = FeaturesKey + KeyDelimiter + "dataplane-status" + FeatureProcessWatcher = FeaturesKey + KeyDelimiter + "process-watcher" + FeatureFileWatcher = FeaturesKey + KeyDelimiter + "file-watcher" + FeatureActivityEvents = FeaturesKey + KeyDelimiter + "activity-events" +) + +func GetDefaultFeatures() []string { + return []string{ + FeatureRegistration, + FeatureNginxConfig, + FeatureNginxSSLConfig, + FeatureNginxCounting, + FeatureNginxConfigAsync, + FeatureMetrics, + FeatureMetricsThrottle, + FeatureDataPlaneStatus, + FeatureProcessWatcher, + FeatureFileWatcher, + FeatureActivityEvents, + } +} diff --git a/sdk/proto/agent.pb.go b/sdk/proto/agent.pb.go index 61affae6b..f0335e02e 100644 --- a/sdk/proto/agent.pb.go +++ b/sdk/proto/agent.pb.go @@ -553,6 +553,7 @@ type AgentMeta struct { InstanceGroup string `protobuf:"bytes,5,opt,name=instance_group,json=instanceGroup,proto3" json:"instance_group"` Updated *types.Timestamp `protobuf:"bytes,6,opt,name=updated,proto3" json:"updated"` SystemUid string `protobuf:"bytes,7,opt,name=system_uid,json=systemUid,proto3" json:"system_uid"` + AgentDetails *AgentDetails `protobuf:"bytes,8,opt,name=agent_details,json=agentDetails,proto3" json:"agent_details"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -633,6 +634,13 @@ func (m *AgentMeta) GetSystemUid() string { return "" } +func (m *AgentMeta) GetAgentDetails() *AgentDetails { + if m != nil { + return m.AgentDetails + } + return nil +} + func init() { proto.RegisterEnum("f5.nginx.agent.sdk.AgentConnectStatus_StatusCode", AgentConnectStatus_StatusCode_name, AgentConnectStatus_StatusCode_value) proto.RegisterEnum("f5.nginx.agent.sdk.AgentLogging_Level", AgentLogging_Level_name, AgentLogging_Level_value) @@ -649,74 +657,75 @@ func init() { func init() { proto.RegisterFile("agent.proto", fileDescriptor_56ede974c0020f77) } var fileDescriptor_56ede974c0020f77 = []byte{ - // 1060 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xcd, 0x6e, 0x23, 0x45, - 0x10, 0xde, 0xf1, 0x4f, 0x6c, 0x97, 0xb3, 0xd9, 0x51, 0xef, 0x0a, 0xbc, 0x66, 0xc9, 0x58, 0x16, - 0x2c, 0x46, 0x82, 0x31, 0x78, 0x85, 0x10, 0x2c, 0x17, 0x3b, 0xf6, 0x66, 0x37, 0x1b, 0x6c, 0xd4, - 0x71, 0xb4, 0x12, 0x97, 0x51, 0xc7, 0xd3, 0x9e, 0x1d, 0xe2, 0x99, 0x36, 0xd3, 0xed, 0xe0, 0xec, - 0x23, 0xf0, 0x22, 0x5c, 0x78, 0x00, 0x1e, 0x80, 0x03, 0x47, 0x9e, 0xc0, 0x42, 0x39, 0xa1, 0x39, - 0x73, 0xe1, 0x86, 0xfa, 0x67, 0x12, 0x87, 0xfc, 0xc0, 0xa5, 0xbb, 0xea, 0xeb, 0xaa, 0xea, 0xaa, - 0xea, 0xaa, 0x9a, 0x81, 0x2a, 0x09, 0x68, 0x2c, 0xdc, 0x79, 0xc2, 0x04, 0x43, 0x68, 0xfa, 0x99, - 0x1b, 0x07, 0x61, 0xbc, 0x74, 0x35, 0xca, 0xfd, 0xe3, 0x3a, 0x04, 0x2c, 0x60, 0xfa, 0xbc, 0x0e, - 0xaf, 0x19, 0x37, 0xb2, 0xf5, 0xcd, 0x09, 0x8b, 0xa7, 0x61, 0x60, 0xb8, 0xaa, 0x56, 0xd3, 0x8c, - 0x13, 0x30, 0x16, 0xcc, 0x68, 0x5b, 0x71, 0x47, 0x8b, 0x69, 0x5b, 0x84, 0x11, 0xe5, 0x82, 0x44, - 0x73, 0x23, 0xf0, 0xd0, 0x9f, 0x7b, 0x9c, 0x4d, 0xc5, 0x0f, 0x24, 0xa1, 0x9e, 0x4f, 0x05, 0x09, - 0x67, 0x5c, 0x1f, 0x35, 0xff, 0xca, 0xc1, 0xfd, 0xae, 0xbc, 0x7c, 0x87, 0xc5, 0x31, 0x9d, 0x08, - 0x4c, 0xbf, 0x5f, 0x50, 0x2e, 0xd0, 0x53, 0x28, 0x44, 0x54, 0x90, 0x5a, 0xae, 0x61, 0xb5, 0xaa, - 0x9d, 0x77, 0xdd, 0xab, 0x9e, 0xba, 0x4a, 0xed, 0x6b, 0x2a, 0x48, 0xaf, 0x9c, 0xae, 0x1c, 0x25, - 0x8e, 0xd5, 0x8a, 0x76, 0xa1, 0x64, 0x6e, 0xa9, 0xe5, 0x1b, 0xf9, 0x56, 0xb5, 0xd3, 0xb8, 0x4e, - 0x7f, 0x28, 0xf9, 0xbe, 0x96, 0xeb, 0x55, 0xd3, 0x95, 0x93, 0x29, 0xe1, 0x8c, 0x40, 0x5f, 0x42, - 0x41, 0xa6, 0xa0, 0x56, 0x50, 0x5e, 0x3c, 0xba, 0xce, 0xca, 0x73, 0xc6, 0xc5, 0x8b, 0x78, 0xca, - 0xb4, 0x13, 0x52, 0x1a, 0xab, 0x15, 0xfd, 0x68, 0x41, 0xdd, 0x27, 0x82, 0xcc, 0x67, 0x24, 0xa6, - 0x57, 0xc2, 0xaf, 0x15, 0x95, 0x63, 0x1f, 0x5d, 0x67, 0xb2, 0x9f, 0x69, 0x1d, 0x18, 0xa5, 0xcc, - 0xc9, 0xed, 0x74, 0xe5, 0xdc, 0x62, 0x13, 0xd7, 0xfc, 0x1b, 0x34, 0xf7, 0x0a, 0x65, 0xcb, 0xce, - 0xe1, 0x72, 0xe8, 0xd3, 0x58, 0x84, 0xe2, 0xb4, 0xf9, 0x73, 0x0e, 0xd0, 0x7a, 0xda, 0x0f, 0x04, - 0x11, 0x0b, 0x8e, 0x8e, 0x00, 0xb8, 0xa2, 0x76, 0x98, 0x4f, 0x6b, 0x56, 0xc3, 0x6a, 0x6d, 0x75, - 0x3e, 0xbd, 0x31, 0xf7, 0x97, 0x74, 0xdd, 0x83, 0x73, 0xc5, 0xde, 0xbd, 0x74, 0xe5, 0x54, 0xb5, - 0x21, 0x6f, 0xc2, 0x7c, 0x8a, 0xd7, 0xac, 0xa2, 0xf7, 0xa1, 0x14, 0x51, 0xce, 0x49, 0x40, 0xd5, - 0xe3, 0x56, 0x74, 0xea, 0x0d, 0x84, 0x33, 0x02, 0x39, 0x50, 0xa4, 0x49, 0xc2, 0x92, 0x5a, 0x5e, - 0x09, 0x55, 0xd2, 0x95, 0xa3, 0x01, 0xac, 0xb7, 0xe6, 0x77, 0x00, 0x17, 0x57, 0xa2, 0xfb, 0x70, - 0x6f, 0x67, 0x34, 0x1c, 0x0e, 0x76, 0xc6, 0xde, 0xe1, 0xf0, 0xe5, 0x70, 0xf4, 0x6a, 0x68, 0xdf, - 0x41, 0x5b, 0x00, 0x19, 0x38, 0x7a, 0x69, 0x5b, 0xa8, 0x0e, 0x6f, 0x65, 0x3c, 0x1e, 0xec, 0x0d, - 0x76, 0xc6, 0x83, 0xbe, 0x37, 0x1a, 0x3f, 0x1f, 0x60, 0x3b, 0x87, 0xde, 0x81, 0xb7, 0xaf, 0x9c, - 0xf5, 0x0f, 0xbf, 0xf1, 0x5e, 0xf4, 0xed, 0x7c, 0xf3, 0x17, 0x0b, 0x1e, 0x5c, 0xae, 0x52, 0x3e, - 0x67, 0x31, 0xa7, 0x68, 0x0c, 0x9b, 0x2a, 0x29, 0x9e, 0xee, 0x0e, 0x95, 0xb2, 0x6a, 0xc7, 0xb9, - 0x2d, 0x65, 0xd3, 0x30, 0xe8, 0xd9, 0xe9, 0xca, 0xb9, 0xa4, 0x88, 0x75, 0x5f, 0xea, 0x63, 0xb4, - 0x07, 0x1b, 0x3a, 0x61, 0xa6, 0xfc, 0x1f, 0xff, 0xbf, 0x27, 0xe8, 0x41, 0xba, 0x72, 0x8c, 0x26, - 0x36, 0x7b, 0xf3, 0xc1, 0xc5, 0x43, 0xcb, 0x7b, 0x74, 0x7b, 0x35, 0xff, 0xb4, 0xa0, 0xba, 0x06, - 0xaf, 0x77, 0x8c, 0x0e, 0xa1, 0x71, 0xe3, 0x95, 0xb7, 0x77, 0xcc, 0x2e, 0x94, 0x66, 0x2c, 0x08, - 0x68, 0x92, 0xf9, 0x7e, 0xb3, 0xa1, 0x7d, 0x16, 0x04, 0x61, 0x1c, 0x68, 0x43, 0x46, 0x09, 0x67, - 0x84, 0x34, 0xa4, 0x53, 0xc3, 0x55, 0x05, 0xdc, 0x60, 0x28, 0x8b, 0x6a, 0xce, 0x12, 0xa1, 0x0d, - 0x19, 0x25, 0x9c, 0x11, 0xcd, 0x9f, 0x2c, 0xd8, 0x5c, 0x77, 0x1c, 0xb5, 0xa0, 0x3c, 0xa5, 0x44, - 0x2c, 0x12, 0x2a, 0x83, 0xcd, 0xb7, 0x2a, 0xbd, 0xcd, 0x74, 0xe5, 0x9c, 0x63, 0xf8, 0x9c, 0x42, - 0x2e, 0x00, 0x5d, 0x0a, 0x1a, 0xf3, 0x90, 0xc5, 0x32, 0x1e, 0x29, 0xbb, 0x95, 0xae, 0x9c, 0x35, - 0x14, 0xaf, 0xd1, 0xe8, 0x11, 0x14, 0x04, 0x09, 0xf4, 0xd0, 0xa9, 0xe8, 0x81, 0x20, 0x79, 0xac, - 0x56, 0x59, 0xd1, 0x64, 0x16, 0x12, 0xae, 0xa6, 0x89, 0xa9, 0x68, 0x05, 0x60, 0xbd, 0x35, 0xff, - 0xce, 0x19, 0x4f, 0x4d, 0x66, 0xd0, 0x2e, 0x14, 0x67, 0xf4, 0x84, 0xce, 0x4c, 0x27, 0x3e, 0xfe, - 0xaf, 0x54, 0xba, 0xfb, 0x52, 0x5a, 0x5b, 0x56, 0x8a, 0x58, 0x6f, 0xe8, 0x21, 0xe4, 0xfd, 0x30, - 0x31, 0xfd, 0x56, 0x4a, 0x57, 0x8e, 0x64, 0xb1, 0x5c, 0xa4, 0xcf, 0xd3, 0x70, 0x46, 0x4d, 0x9b, - 0x29, 0x9f, 0x25, 0x8f, 0xd5, 0x8a, 0x3e, 0x80, 0x72, 0x44, 0x96, 0x1e, 0x0f, 0xdf, 0x50, 0xe5, - 0xf6, 0x5d, 0x9d, 0xab, 0x0c, 0xc3, 0xa5, 0x88, 0x2c, 0x0f, 0xc2, 0x37, 0x14, 0x7d, 0x02, 0x55, - 0x09, 0x1e, 0x91, 0xc9, 0xf1, 0x62, 0x2e, 0xa7, 0x9b, 0x94, 0x55, 0x73, 0x60, 0x0d, 0xc6, 0x10, - 0x91, 0x65, 0x4f, 0xd3, 0xe8, 0x3d, 0x90, 0xca, 0x9e, 0x9c, 0x03, 0x1b, 0x4a, 0x5a, 0xcf, 0x01, - 0x0d, 0xe1, 0x8d, 0x88, 0x2c, 0xbb, 0x01, 0x95, 0x8f, 0x35, 0x61, 0xd1, 0x3c, 0xa1, 0x9c, 0xd7, - 0x4a, 0x0d, 0xab, 0x55, 0xd6, 0x0e, 0x64, 0x18, 0x3e, 0xa7, 0x9a, 0x5f, 0x41, 0x51, 0x85, 0x8f, - 0xca, 0x50, 0x78, 0x31, 0x7c, 0x36, 0xb2, 0xef, 0xa0, 0x0a, 0x14, 0xfb, 0x83, 0xde, 0xe1, 0xae, - 0x6d, 0x49, 0xf0, 0x55, 0x17, 0x0f, 0xed, 0x9c, 0x04, 0x07, 0x18, 0x8f, 0xb0, 0x9d, 0x97, 0xe4, - 0xb3, 0xee, 0xb8, 0xbb, 0x6f, 0x17, 0x9a, 0xbf, 0xe6, 0xa0, 0x72, 0xfe, 0x41, 0x91, 0x33, 0xea, - 0x84, 0x26, 0xf2, 0x51, 0x55, 0xea, 0xcd, 0x8c, 0x32, 0x10, 0xce, 0x08, 0xf4, 0x04, 0x36, 0xfd, - 0x90, 0xcf, 0x67, 0xe4, 0xd4, 0x8b, 0x49, 0x94, 0xcd, 0x33, 0xd5, 0xdc, 0xeb, 0x38, 0xae, 0x1a, - 0x6e, 0x48, 0x22, 0x2a, 0xdf, 0x42, 0x90, 0xc0, 0xd4, 0x88, 0x7a, 0x0b, 0x41, 0x02, 0x2c, 0x17, - 0xf4, 0x05, 0x6c, 0x85, 0x31, 0x17, 0x24, 0x9e, 0x50, 0x2f, 0x48, 0xd8, 0x62, 0xae, 0xf2, 0x58, - 0xe9, 0xa1, 0x74, 0xe5, 0xfc, 0xeb, 0x04, 0xdf, 0xcd, 0xf8, 0x5d, 0xc9, 0xa2, 0x2e, 0x94, 0x16, - 0x73, 0x9f, 0x08, 0xea, 0xab, 0x6c, 0x56, 0x3b, 0x75, 0x57, 0x7f, 0x95, 0xdd, 0xec, 0xab, 0xec, - 0x8e, 0xb3, 0xaf, 0xb2, 0x8e, 0xc6, 0x88, 0xe3, 0x8c, 0x40, 0x1f, 0x03, 0xf0, 0x53, 0x2e, 0x68, - 0xe4, 0x2d, 0x42, 0x5f, 0x25, 0xdb, 0x54, 0xfb, 0x05, 0x8a, 0x2b, 0x9a, 0x3e, 0x0c, 0xfd, 0xbd, - 0x42, 0xb9, 0x60, 0x17, 0x2f, 0xdc, 0x50, 0x91, 0xf6, 0x3e, 0xff, 0xed, 0x6c, 0xdb, 0xfa, 0xfd, - 0x6c, 0xdb, 0xfa, 0xe3, 0x6c, 0xdb, 0xfa, 0xf6, 0xc3, 0x20, 0x14, 0xaf, 0x17, 0x47, 0xee, 0x84, - 0x45, 0x6d, 0x55, 0xb7, 0x6d, 0x55, 0xb7, 0x6d, 0xee, 0x1f, 0xb7, 0x4f, 0x3a, 0xfa, 0x7f, 0xe1, - 0xa9, 0xf6, 0x6f, 0x43, 0x6d, 0x4f, 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0x02, 0x48, 0xb6, 0x2c, - 0xa0, 0x08, 0x00, 0x00, + // 1081 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xcd, 0x72, 0x1b, 0x45, + 0x10, 0xce, 0xea, 0xc7, 0x92, 0x5a, 0xb6, 0xb3, 0x4c, 0x52, 0xa0, 0x88, 0xe0, 0x55, 0xa9, 0x20, + 0x88, 0x2a, 0x58, 0x81, 0x52, 0x14, 0x05, 0xe1, 0x22, 0x59, 0x8a, 0x63, 0xc7, 0x48, 0xd4, 0x58, + 0xae, 0x50, 0x5c, 0xb6, 0xc6, 0xda, 0xd1, 0x66, 0xb1, 0x76, 0x57, 0xec, 0x8c, 0x8c, 0x9c, 0x47, + 0xe0, 0x21, 0xb8, 0x72, 0xe1, 0x01, 0x78, 0x04, 0x8e, 0x3c, 0xc1, 0x16, 0xe5, 0x13, 0xb5, 0x67, + 0x2e, 0xdc, 0xa8, 0xf9, 0x59, 0x5b, 0xc6, 0x3f, 0xc9, 0x65, 0xb6, 0xfb, 0x9b, 0xee, 0x9e, 0x9e, + 0x6f, 0xa6, 0x7b, 0x16, 0xaa, 0xc4, 0xa3, 0x21, 0xb7, 0xe7, 0x71, 0xc4, 0x23, 0x84, 0xa6, 0x9f, + 0xdb, 0xa1, 0xe7, 0x87, 0x4b, 0x5b, 0xa1, 0xcc, 0x3d, 0xae, 0x83, 0x17, 0x79, 0x91, 0x9a, 0xaf, + 0xc3, 0xcb, 0x88, 0x69, 0xdb, 0xfa, 0xfa, 0x24, 0x0a, 0xa7, 0xbe, 0xa7, 0xb5, 0xaa, 0x72, 0x53, + 0x8a, 0xe5, 0x45, 0x91, 0x37, 0xa3, 0x6d, 0xa9, 0x1d, 0x2d, 0xa6, 0x6d, 0xee, 0x07, 0x94, 0x71, + 0x12, 0xcc, 0xb5, 0xc1, 0x03, 0x77, 0xee, 0xb0, 0x68, 0xca, 0x7f, 0x22, 0x31, 0x75, 0x5c, 0xca, + 0x89, 0x3f, 0x63, 0x6a, 0xaa, 0xf9, 0x4f, 0x0e, 0xee, 0x75, 0xc5, 0xe2, 0xdb, 0x51, 0x18, 0xd2, + 0x09, 0xc7, 0xf4, 0xc7, 0x05, 0x65, 0x1c, 0x3d, 0x81, 0x42, 0x40, 0x39, 0xa9, 0xe5, 0x1a, 0x46, + 0xab, 0xda, 0x79, 0xcf, 0xbe, 0x9a, 0xa9, 0x2d, 0xdd, 0xbe, 0xa1, 0x9c, 0xf4, 0xca, 0x69, 0x62, + 0x49, 0x73, 0x2c, 0x47, 0xb4, 0x03, 0x25, 0xbd, 0x4a, 0x2d, 0xdf, 0xc8, 0xb7, 0xaa, 0x9d, 0xc6, + 0x75, 0xfe, 0x43, 0xa1, 0xf7, 0x95, 0x5d, 0xaf, 0x9a, 0x26, 0x56, 0xe6, 0x84, 0x33, 0x01, 0x7d, + 0x05, 0x05, 0x41, 0x41, 0xad, 0x20, 0xb3, 0x78, 0x78, 0x5d, 0x94, 0x67, 0x11, 0xe3, 0xbb, 0xe1, + 0x34, 0x52, 0x49, 0x08, 0x6b, 0x2c, 0x47, 0xf4, 0xb3, 0x01, 0x75, 0x97, 0x70, 0x32, 0x9f, 0x91, + 0x90, 0x5e, 0xd9, 0x7e, 0xad, 0x28, 0x13, 0xfb, 0xf8, 0xba, 0x90, 0xfd, 0xcc, 0xeb, 0x40, 0x3b, + 0x65, 0x49, 0x6e, 0xa5, 0x89, 0x75, 0x4b, 0x4c, 0x5c, 0x73, 0x6f, 0xf0, 0xdc, 0x2b, 0x94, 0x0d, + 0x33, 0x87, 0xcb, 0xbe, 0x4b, 0x43, 0xee, 0xf3, 0xd3, 0xe6, 0x6f, 0x39, 0x40, 0xab, 0xb4, 0x1f, + 0x70, 0xc2, 0x17, 0x0c, 0x1d, 0x01, 0x30, 0x29, 0x6d, 0x47, 0x2e, 0xad, 0x19, 0x0d, 0xa3, 0xb5, + 0xd9, 0xf9, 0xec, 0x46, 0xee, 0x2f, 0xf9, 0xda, 0x07, 0xe7, 0x8e, 0xbd, 0xbb, 0x69, 0x62, 0x55, + 0x55, 0x20, 0x67, 0x12, 0xb9, 0x14, 0xaf, 0x44, 0x45, 0x1f, 0x40, 0x29, 0xa0, 0x8c, 0x11, 0x8f, + 0xca, 0xc3, 0xad, 0x28, 0xea, 0x35, 0x84, 0x33, 0x01, 0x59, 0x50, 0xa4, 0x71, 0x1c, 0xc5, 0xb5, + 0xbc, 0x34, 0xaa, 0xa4, 0x89, 0xa5, 0x00, 0xac, 0x3e, 0xcd, 0x1f, 0x00, 0x2e, 0x96, 0x44, 0xf7, + 0xe0, 0xee, 0xf6, 0x68, 0x38, 0x1c, 0x6c, 0x8f, 0x9d, 0xc3, 0xe1, 0xf3, 0xe1, 0xe8, 0xc5, 0xd0, + 0xbc, 0x83, 0x36, 0x01, 0x32, 0x70, 0xf4, 0xdc, 0x34, 0x50, 0x1d, 0xde, 0xce, 0x74, 0x3c, 0xd8, + 0x1b, 0x6c, 0x8f, 0x07, 0x7d, 0x67, 0x34, 0x7e, 0x36, 0xc0, 0x66, 0x0e, 0xbd, 0x0b, 0xef, 0x5c, + 0x99, 0xeb, 0x1f, 0x7e, 0xeb, 0xec, 0xf6, 0xcd, 0x7c, 0xf3, 0x77, 0x03, 0xee, 0x5f, 0xbe, 0xa5, + 0x6c, 0x1e, 0x85, 0x8c, 0xa2, 0x31, 0xac, 0x4b, 0x52, 0x1c, 0x55, 0x1d, 0x92, 0xb2, 0x6a, 0xc7, + 0xba, 0x8d, 0xb2, 0xa9, 0xef, 0xf5, 0xcc, 0x34, 0xb1, 0x2e, 0x39, 0x62, 0x55, 0x97, 0x6a, 0x1a, + 0xed, 0xc1, 0x9a, 0x22, 0x4c, 0x5f, 0xff, 0x47, 0x6f, 0x76, 0x04, 0x3d, 0x48, 0x13, 0x4b, 0x7b, + 0x62, 0xfd, 0x6d, 0xde, 0xbf, 0x38, 0x68, 0xb1, 0x8e, 0x2a, 0xaf, 0xe6, 0xdf, 0x06, 0x54, 0x57, + 0xe0, 0xd5, 0x8a, 0x51, 0x5b, 0x68, 0xdc, 0xb8, 0xe4, 0xed, 0x15, 0xb3, 0x03, 0xa5, 0x59, 0xe4, + 0x79, 0x34, 0xce, 0x72, 0xbf, 0x39, 0xd0, 0x7e, 0xe4, 0x79, 0x7e, 0xe8, 0xa9, 0x40, 0xda, 0x09, + 0x67, 0x82, 0x08, 0xa4, 0xa8, 0x61, 0xf2, 0x06, 0xdc, 0x10, 0x28, 0xdb, 0xd5, 0x3c, 0x8a, 0xb9, + 0x0a, 0xa4, 0x9d, 0x70, 0x26, 0x34, 0x7f, 0x35, 0x60, 0x7d, 0x35, 0x71, 0xd4, 0x82, 0xf2, 0x94, + 0x12, 0xbe, 0x88, 0xa9, 0xd8, 0x6c, 0xbe, 0x55, 0xe9, 0xad, 0xa7, 0x89, 0x75, 0x8e, 0xe1, 0x73, + 0x09, 0xd9, 0x00, 0x74, 0xc9, 0x69, 0xc8, 0xfc, 0x28, 0x14, 0xfb, 0x11, 0xb6, 0x9b, 0x69, 0x62, + 0xad, 0xa0, 0x78, 0x45, 0x46, 0x0f, 0xa1, 0xc0, 0x89, 0xa7, 0x9a, 0x4e, 0x45, 0x35, 0x04, 0xa1, + 0x63, 0x39, 0x8a, 0x1b, 0x4d, 0x66, 0x3e, 0x61, 0xb2, 0x9b, 0xe8, 0x1b, 0x2d, 0x01, 0xac, 0x3e, + 0xcd, 0x7f, 0x73, 0x3a, 0x53, 0xcd, 0x0c, 0xda, 0x81, 0xe2, 0x8c, 0x9e, 0xd0, 0x99, 0xae, 0xc4, + 0x47, 0xaf, 0xa3, 0xd2, 0xde, 0x17, 0xd6, 0x2a, 0xb2, 0x74, 0xc4, 0xea, 0x83, 0x1e, 0x40, 0xde, + 0xf5, 0x63, 0x5d, 0x6f, 0xa5, 0x34, 0xb1, 0x84, 0x8a, 0xc5, 0x20, 0x72, 0x9e, 0xfa, 0x33, 0xaa, + 0xcb, 0x4c, 0xe6, 0x2c, 0x74, 0x2c, 0x47, 0xf4, 0x21, 0x94, 0x03, 0xb2, 0x74, 0x98, 0xff, 0x8a, + 0xca, 0xb4, 0x37, 0x14, 0x57, 0x19, 0x86, 0x4b, 0x01, 0x59, 0x1e, 0xf8, 0xaf, 0x28, 0xfa, 0x14, + 0xaa, 0x02, 0x3c, 0x22, 0x93, 0xe3, 0xc5, 0x5c, 0x74, 0x37, 0x61, 0x2b, 0xfb, 0xc0, 0x0a, 0x8c, + 0x21, 0x20, 0xcb, 0x9e, 0x92, 0xd1, 0xfb, 0x20, 0x9c, 0x1d, 0xd1, 0x07, 0xd6, 0xa4, 0xb5, 0xea, + 0x03, 0x0a, 0xc2, 0x6b, 0x01, 0x59, 0x76, 0x3d, 0x2a, 0x0e, 0x6b, 0x12, 0x05, 0xf3, 0x98, 0x32, + 0x56, 0x2b, 0x35, 0x8c, 0x56, 0x59, 0x25, 0x90, 0x61, 0xf8, 0x5c, 0x6a, 0x7e, 0x0d, 0x45, 0xb9, + 0x7d, 0x54, 0x86, 0xc2, 0xee, 0xf0, 0xe9, 0xc8, 0xbc, 0x83, 0x2a, 0x50, 0xec, 0x0f, 0x7a, 0x87, + 0x3b, 0xa6, 0x21, 0xc0, 0x17, 0x5d, 0x3c, 0x34, 0x73, 0x02, 0x1c, 0x60, 0x3c, 0xc2, 0x66, 0x5e, + 0x88, 0x4f, 0xbb, 0xe3, 0xee, 0xbe, 0x59, 0x68, 0xfe, 0x92, 0x87, 0xca, 0xf9, 0x83, 0x22, 0x7a, + 0xd4, 0x09, 0x8d, 0xc5, 0xa1, 0x4a, 0xea, 0x75, 0x8f, 0xd2, 0x10, 0xce, 0x04, 0xf4, 0x18, 0xd6, + 0x5d, 0x9f, 0xcd, 0x67, 0xe4, 0xd4, 0x09, 0x49, 0x90, 0xf5, 0x33, 0x59, 0xdc, 0xab, 0x38, 0xae, + 0x6a, 0x6d, 0x48, 0x02, 0x2a, 0xce, 0x82, 0x13, 0x4f, 0xdf, 0x11, 0x79, 0x16, 0x9c, 0x78, 0x58, + 0x0c, 0xe8, 0x4b, 0xd8, 0xf4, 0x43, 0xc6, 0x49, 0x38, 0xa1, 0x8e, 0x17, 0x47, 0x8b, 0xb9, 0xe4, + 0xb1, 0xd2, 0x43, 0x69, 0x62, 0xfd, 0x6f, 0x06, 0x6f, 0x64, 0xfa, 0x8e, 0x50, 0x51, 0x17, 0x4a, + 0x8b, 0xb9, 0x4b, 0x38, 0x75, 0x25, 0x9b, 0xd5, 0x4e, 0xdd, 0x56, 0xaf, 0xb2, 0x9d, 0xbd, 0xca, + 0xf6, 0x38, 0x7b, 0x95, 0xd5, 0x6e, 0xb4, 0x39, 0xce, 0x04, 0xf4, 0x09, 0x00, 0x3b, 0x65, 0x9c, + 0x06, 0xce, 0xc2, 0x77, 0x25, 0xd9, 0xfa, 0xb6, 0x5f, 0xa0, 0xb8, 0xa2, 0xe4, 0x43, 0xdf, 0x45, + 0xdf, 0xc1, 0x86, 0xea, 0x60, 0x59, 0xe3, 0x28, 0xbf, 0x61, 0xe3, 0x78, 0x2b, 0x4d, 0xac, 0xcb, + 0xae, 0x58, 0xf5, 0xc2, 0x8b, 0xc7, 0xaa, 0x60, 0x16, 0x2f, 0x36, 0x28, 0x39, 0xec, 0x7d, 0xf1, + 0xc7, 0xd9, 0x96, 0xf1, 0xe7, 0xd9, 0x96, 0xf1, 0xd7, 0xd9, 0x96, 0xf1, 0xfd, 0x47, 0x9e, 0xcf, + 0x5f, 0x2e, 0x8e, 0xec, 0x49, 0x14, 0xb4, 0xe5, 0x62, 0x6d, 0x19, 0xa1, 0xcd, 0xdc, 0xe3, 0xf6, + 0x49, 0x47, 0xfd, 0x89, 0x3c, 0x51, 0x3b, 0x5f, 0x93, 0x9f, 0xc7, 0xff, 0x05, 0x00, 0x00, 0xff, + 0xff, 0xb4, 0x95, 0x5a, 0x2d, 0xfa, 0x08, 0x00, 0x00, } func (m *AgentConnectRequest) Marshal() (dAtA []byte, err error) { @@ -1141,6 +1150,18 @@ func (m *AgentMeta) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.AgentDetails != nil { + { + size, err := m.AgentDetails.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAgent(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } if len(m.SystemUid) > 0 { i -= len(m.SystemUid) copy(dAtA[i:], m.SystemUid) @@ -1416,6 +1437,10 @@ func (m *AgentMeta) Size() (n int) { if l > 0 { n += 1 + l + sovAgent(uint64(l)) } + if m.AgentDetails != nil { + l = m.AgentDetails.Size() + n += 1 + l + sovAgent(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -2701,6 +2726,42 @@ func (m *AgentMeta) Unmarshal(dAtA []byte) error { } m.SystemUid = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AgentDetails", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAgent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAgent + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAgent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AgentDetails == nil { + m.AgentDetails = &AgentDetails{} + } + if err := m.AgentDetails.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAgent(dAtA[iNdEx:]) diff --git a/sdk/proto/agent.proto b/sdk/proto/agent.proto index 92894732f..7aa32e2e0 100644 --- a/sdk/proto/agent.proto +++ b/sdk/proto/agent.proto @@ -78,4 +78,5 @@ message AgentMeta { string instance_group = 5 [(gogoproto.jsontag) = "instance_group"]; google.protobuf.Timestamp updated = 6 [(gogoproto.jsontag) = "updated"]; string system_uid = 7 [(gogoproto.jsontag) = "system_uid"]; + AgentDetails agent_details = 8 [(gogoproto.jsontag) = "agent_details"]; } diff --git a/src/core/config/config.go b/src/core/config/config.go index 1d89affea..2babeb75f 100644 --- a/src/core/config/config.go +++ b/src/core/config/config.go @@ -10,6 +10,7 @@ import ( "strings" "time" + agent_config "github.com/nginx/agent/sdk/v2/agent/config" advanced_metrics "github.com/nginx/agent/v2/src/extensions/advanced-metrics/pkg/advanced-metrics" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -40,7 +41,7 @@ const ( ) var ( - Viper = viper.NewWithOptions(viper.KeyDelimiter(KeyDelimiter)) + Viper = viper.NewWithOptions(viper.KeyDelimiter(agent_config.KeyDelimiter)) ) func SetVersion(version, commit string) { @@ -177,7 +178,7 @@ func GetConfig(clientId string) (*Config, error) { Nginx: getNginx(), Dataplane: getDataplane(), AgentMetrics: getMetrics(), - Features: Viper.GetStringSlice(FeaturesKey), + Features: Viper.GetStringSlice(agent_config.FeaturesKey), Tags: Viper.GetStringSlice(TagsKey), Updated: filePathUTime(Viper.GetString(DynamicConfigPathKey)), AllowedDirectoriesMap: map[string]struct{}{}, @@ -231,8 +232,8 @@ func UpdateAgentConfig(systemId string, updateTags []string, updateFeatures []st sort.Strings(config.Features) synchronizedFeatures := reflect.DeepEqual(updateFeatures, config.Features) - Viper.Set(FeaturesKey, updateFeatures) - config.Features = Viper.GetStringSlice(FeaturesKey) + Viper.Set(agent_config.FeaturesKey, updateFeatures) + config.Features = Viper.GetStringSlice(agent_config.FeaturesKey) // If the features are already synchronized there is no need to overwrite if synchronizedTags && synchronizedFeatures { diff --git a/src/core/config/config_test.go b/src/core/config/config_test.go index 7eacef54e..7af6da135 100644 --- a/src/core/config/config_test.go +++ b/src/core/config/config_test.go @@ -12,6 +12,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + agent_config "github.com/nginx/agent/sdk/v2/agent/config" + sysutils "github.com/nginx/agent/v2/test/utils/system" ) @@ -455,7 +457,7 @@ func TestUpdateAgentConfig(t *testing.T) { } func setEnvVariable(t *testing.T, name string, value string) { - key := strings.ToUpper(EnvPrefix + KeyDelimiter + name) + key := strings.ToUpper(EnvPrefix + agent_config.KeyDelimiter + name) err := os.Setenv(key, value) require.NoError(t, err) } @@ -464,7 +466,7 @@ func cleanEnv(t *testing.T, confFileName, dynamicConfFileAbsPath string) { os.Clearenv() ROOT_COMMAND.ResetFlags() ROOT_COMMAND.ResetCommands() - Viper = viper.NewWithOptions(viper.KeyDelimiter(KeyDelimiter)) + Viper = viper.NewWithOptions(viper.KeyDelimiter(agent_config.KeyDelimiter)) SetDefaults() RegisterFlags() diff --git a/src/core/config/defaults.go b/src/core/config/defaults.go index 2fe70c56f..28f8fc4ca 100644 --- a/src/core/config/defaults.go +++ b/src/core/config/defaults.go @@ -5,6 +5,8 @@ import ( "time" "github.com/google/uuid" + + agent_config "github.com/nginx/agent/sdk/v2/agent/config" advanced_metrics "github.com/nginx/agent/v2/src/extensions/advanced-metrics/pkg/advanced-metrics" log "github.com/sirupsen/logrus" ) @@ -78,6 +80,7 @@ var ( PriorityTableMaxSize: 1000, }, }, + Features: agent_config.GetDefaultFeatures(), NAPMonitoring: NAPMonitoring{ ProcessorBufferSize: 50000, CollectorBufferSize: 50000, @@ -86,18 +89,6 @@ var ( ReportInterval: time.Minute, ReportCount: 400, }, - Features: []string{ - FeatureRegistration, - FeatureNginxConfig, - FeatureNginxSSLConfig, - FeatureNginxCounting, - FeatureMetrics, - FeatureMetricsThrottle, - FeatureDataPlaneStatus, - FeatureProcessWatcher, - FeatureFileWatcher, - FeatureActivityEvents, - }, } AllowedDirectoriesMap map[string]struct{} ) @@ -107,7 +98,6 @@ const ( DynamicConfigFileAbsPath = "/etc/nginx-agent/agent-dynamic.conf" ConfigFileName = "nginx-agent.conf" ConfigFileType = "yaml" - KeyDelimiter = "_" EnvPrefix = "nms" ConfigPathKey = "path" DynamicConfigPathKey = "dynamic-config-path" @@ -122,91 +112,77 @@ const ( // viper keys used in config LogKey = "log" - LogLevel = LogKey + KeyDelimiter + "level" - LogPath = LogKey + KeyDelimiter + "path" + LogLevel = LogKey + agent_config.KeyDelimiter + "level" + LogPath = LogKey + agent_config.KeyDelimiter + "path" // viper keys used in config ServerKey = "server" - ServerHost = ServerKey + KeyDelimiter + "host" - ServerGrpcport = ServerKey + KeyDelimiter + "grpcport" - ServerToken = ServerKey + KeyDelimiter + "token" - ServerMetrics = ServerKey + KeyDelimiter + "metrics" - ServerCommand = ServerKey + KeyDelimiter + "command" + ServerHost = ServerKey + agent_config.KeyDelimiter + "host" + ServerGrpcport = ServerKey + agent_config.KeyDelimiter + "grpcport" + ServerToken = ServerKey + agent_config.KeyDelimiter + "token" + ServerMetrics = ServerKey + agent_config.KeyDelimiter + "metrics" + ServerCommand = ServerKey + agent_config.KeyDelimiter + "command" // viper keys used in config TlsKey = "tls" - TlsEnable = TlsKey + KeyDelimiter + "enable" - TlsCert = TlsKey + KeyDelimiter + "cert" - TlsPrivateKey = TlsKey + KeyDelimiter + "key" - TlsCa = TlsKey + KeyDelimiter + "ca" - TlsSkipVerify = TlsKey + KeyDelimiter + "skip_verify" + TlsEnable = TlsKey + agent_config.KeyDelimiter + "enable" + TlsCert = TlsKey + agent_config.KeyDelimiter + "cert" + TlsPrivateKey = TlsKey + agent_config.KeyDelimiter + "key" + TlsCa = TlsKey + agent_config.KeyDelimiter + "ca" + TlsSkipVerify = TlsKey + agent_config.KeyDelimiter + "skip_verify" // viper keys used in config NginxKey = "nginx" - NginxExcludeLogs = NginxKey + KeyDelimiter + "exclude_logs" - NginxDebug = NginxKey + KeyDelimiter + "debug" - NginxCountingSocket = NginxKey + KeyDelimiter + "socket" - NginxClientVersion = NginxKey + KeyDelimiter + "client_version" + NginxExcludeLogs = NginxKey + agent_config.KeyDelimiter + "exclude_logs" + NginxDebug = NginxKey + agent_config.KeyDelimiter + "debug" + NginxCountingSocket = NginxKey + agent_config.KeyDelimiter + "socket" + NginxClientVersion = NginxKey + agent_config.KeyDelimiter + "client_version" // viper keys used in config DataplaneKey = "dataplane" - DataplaneEventsEnable = DataplaneKey + KeyDelimiter + "events_enable" - DataplaneSyncEnable = DataplaneKey + KeyDelimiter + "sync_enable" - DataplaneStatusPoll = DataplaneKey + KeyDelimiter + "status_poll_interval" - DataplaneStatusReportInterval = DataplaneKey + KeyDelimiter + "report_interval" + DataplaneEventsEnable = DataplaneKey + agent_config.KeyDelimiter + "events_enable" + DataplaneSyncEnable = DataplaneKey + agent_config.KeyDelimiter + "sync_enable" + DataplaneStatusPoll = DataplaneKey + agent_config.KeyDelimiter + "status_poll_interval" + DataplaneStatusReportInterval = DataplaneKey + agent_config.KeyDelimiter + "report_interval" // viper keys used in config MetricsKey = "metrics" - MetricsBulkSize = MetricsKey + KeyDelimiter + "bulk_size" - MetricsReportInterval = MetricsKey + KeyDelimiter + "report_interval" - MetricsCollectionInterval = MetricsKey + KeyDelimiter + "collection_interval" - MetricsMode = MetricsKey + KeyDelimiter + "mode" + MetricsBulkSize = MetricsKey + agent_config.KeyDelimiter + "bulk_size" + MetricsReportInterval = MetricsKey + agent_config.KeyDelimiter + "report_interval" + MetricsCollectionInterval = MetricsKey + agent_config.KeyDelimiter + "collection_interval" + MetricsMode = MetricsKey + agent_config.KeyDelimiter + "mode" // viper keys used in config AdvancedMetricsKey = "advanced_metrics" - AdvancedMetricsSocketPath = AdvancedMetricsKey + KeyDelimiter + "socket_path" - AdvancedMetricsAggregationPeriod = AdvancedMetricsKey + KeyDelimiter + "aggregation_period" - AdvancedMetricsPublishPeriod = AdvancedMetricsKey + KeyDelimiter + "publishing_period" - AdvancedMetricsTableSizesLimits = AdvancedMetricsKey + KeyDelimiter + "table_sizes_limits" - AdvancedMetricsTableSizesLimitsSTMS = AdvancedMetricsTableSizesLimits + KeyDelimiter + "staging_table_max_size" - AdvancedMetricsTableSizesLimitsSTT = AdvancedMetricsTableSizesLimits + KeyDelimiter + "staging_table_threshold" - AdvancedMetricsTableSizesLimitsPTMS = AdvancedMetricsTableSizesLimits + KeyDelimiter + "priority_table_max_size" - AdvancedMetricsTableSizesLimitsPTT = AdvancedMetricsTableSizesLimits + KeyDelimiter + "priority_table_threshold" + AdvancedMetricsSocketPath = AdvancedMetricsKey + agent_config.KeyDelimiter + "socket_path" + AdvancedMetricsAggregationPeriod = AdvancedMetricsKey + agent_config.KeyDelimiter + "aggregation_period" + AdvancedMetricsPublishPeriod = AdvancedMetricsKey + agent_config.KeyDelimiter + "publishing_period" + AdvancedMetricsTableSizesLimits = AdvancedMetricsKey + agent_config.KeyDelimiter + "table_sizes_limits" + AdvancedMetricsTableSizesLimitsSTMS = AdvancedMetricsTableSizesLimits + agent_config.KeyDelimiter + "staging_table_max_size" + AdvancedMetricsTableSizesLimitsSTT = AdvancedMetricsTableSizesLimits + agent_config.KeyDelimiter + "staging_table_threshold" + AdvancedMetricsTableSizesLimitsPTMS = AdvancedMetricsTableSizesLimits + agent_config.KeyDelimiter + "priority_table_max_size" + AdvancedMetricsTableSizesLimitsPTT = AdvancedMetricsTableSizesLimits + agent_config.KeyDelimiter + "priority_table_threshold" // viper keys used in config NginxAppProtectKey = "nginx_app_protect" - NginxAppProtectReportInterval = NginxAppProtectKey + KeyDelimiter + "report_interval" + NginxAppProtectReportInterval = NginxAppProtectKey + agent_config.KeyDelimiter + "report_interval" // viper keys used in config NAPMonitoringKey = "nap_monitoring" - NAPMonitoringCollectorBufferSize = NAPMonitoringKey + KeyDelimiter + "collector_buffer_size" - NAPMonitoringProcessorBufferSize = NAPMonitoringKey + KeyDelimiter + "processor_buffer_size" - NAPMonitoringSyslogIP = NAPMonitoringKey + KeyDelimiter + "syslog_ip" - NAPMonitoringSyslogPort = NAPMonitoringKey + KeyDelimiter + "syslog_port" - NAPMonitoringReportInterval = NAPMonitoringKey + KeyDelimiter + "report_interval" - NAPMonitoringReportCount = NAPMonitoringKey + KeyDelimiter + "report_count" - - // viper keys used in config - FeaturesKey = "features" - - FeatureRegistration = FeaturesKey + KeyDelimiter + "registration" - FeatureNginxConfig = FeaturesKey + KeyDelimiter + "nginx-config" - FeatureNginxSSLConfig = FeaturesKey + KeyDelimiter + "nginx-ssl-config" - FeatureNginxCounting = FeaturesKey + KeyDelimiter + "nginx-counting" - FeatureMetrics = FeaturesKey + KeyDelimiter + "metrics" - FeatureMetricsThrottle = FeaturesKey + KeyDelimiter + "metrics-throttle" - FeatureDataPlaneStatus = FeaturesKey + KeyDelimiter + "dataplane-status" - FeatureProcessWatcher = FeaturesKey + KeyDelimiter + "process-watcher" - FeatureFileWatcher = FeaturesKey + KeyDelimiter + "file-watcher" - FeatureActivityEvents = FeaturesKey + KeyDelimiter + "activity-events" + NAPMonitoringCollectorBufferSize = NAPMonitoringKey + agent_config.KeyDelimiter + "collector_buffer_size" + NAPMonitoringProcessorBufferSize = NAPMonitoringKey + agent_config.KeyDelimiter + "processor_buffer_size" + NAPMonitoringSyslogIP = NAPMonitoringKey + agent_config.KeyDelimiter + "syslog_ip" + NAPMonitoringSyslogPort = NAPMonitoringKey + agent_config.KeyDelimiter + "syslog_port" + NAPMonitoringReportInterval = NAPMonitoringKey + agent_config.KeyDelimiter + "report_interval" + NAPMonitoringReportCount = NAPMonitoringKey + agent_config.KeyDelimiter + "report_count" // DEPRECATED KEYS NginxBinPathKey = "nginx_bin_path" @@ -268,9 +244,9 @@ var ( Usage: "A comma-separated list of tags to add to the current instance or machine, to be used for inventory purposes.", }, &StringSliceFlag{ - Name: FeaturesKey, + Name: agent_config.FeaturesKey, Usage: "A comma-separated list of features enabled for the agent.", - DefaultValue: Defaults.Features, + DefaultValue: agent_config.GetDefaultFeatures(), }, // NGINX Config &StringFlag{ diff --git a/src/core/config/types.go b/src/core/config/types.go index a04d32037..f932e4b22 100644 --- a/src/core/config/types.go +++ b/src/core/config/types.go @@ -20,6 +20,7 @@ type Config struct { AgentMetrics AgentMetrics `mapstructure:"metrics" yaml:"-"` Tags []string `mapstructure:"tags" yaml:"tags,omitempty"` Features []string `mapstructure:"features" yaml:"features,omitempty"` + Extensions []string `mapstructure:"extensions" yaml:"extensions,omitempty"` Updated time.Time `yaml:"-"` // update time of the config file AllowedDirectoriesMap map[string]struct{} `yaml:"-"` DisplayName string `mapstructure:"display_name" yaml:"display_name,omitempty"` diff --git a/src/core/topics.go b/src/core/topics.go index 6ae1c1eb0..9c251993c 100644 --- a/src/core/topics.go +++ b/src/core/topics.go @@ -19,6 +19,11 @@ const ( NginxWorkerProcCreated = "nginx.worker.created" NginxWorkerProcKilled = "nginx.worker.killed" NginxDetailProcUpdate = "nginx.proc.update" + NginxConfigValidationPending = "nginx.config.validation.pending" + NginxConfigValidationFailed = "nginx.config.validation.failed" + NginxConfigValidationSucceeded = "nginx.config.validation.succeeded" + NginxConfigApplyFailed = "nginx.config.apply.failed" + NginxConfigApplySucceeded = "nginx.config.apply.succeeded" CommPrefix = "comms." CommStatus = CommPrefix + "status" CommMetrics = CommPrefix + "metrics" diff --git a/src/plugins/dataplane_status.go b/src/plugins/dataplane_status.go index bd5dd3ba4..8a8eda177 100644 --- a/src/plugins/dataplane_status.go +++ b/src/plugins/dataplane_status.go @@ -15,22 +15,23 @@ 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 + 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 } const ( @@ -87,11 +88,67 @@ func (dps *DataPlaneStatus) Process(msg *core.Message) { case msg.Exact(core.NginxAppProtectDetailsGenerated): // If a NAP report was generated sync it dps.syncNAPDetails(msg) + + case msg.Exact(core.NginxConfigValidationPending): + log.Tracef("DataplaneStatus: %T message from topic %s received", msg.Data(), msg.Topic()) + switch data := msg.Data().(type) { + case *proto.AgentActivityStatus: + dps.updateAgentActivityStatuses(data) + default: + log.Errorf("Expected the type %T but got %T", &proto.AgentActivityStatus{}, data) + } + case msg.Exact(core.NginxConfigApplyFailed) || msg.Exact(core.NginxConfigApplySucceeded): + 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.sendDataplaneStatus(dps.messagePipeline, false) + dps.removeAgentActivityStatus(data) + default: + log.Errorf("Expected the type %T but got %T", &proto.AgentActivityStatus{}, data) + } } } func (dps *DataPlaneStatus) Subscriptions() []string { - return []string{core.AgentConfigChanged, core.NginxAppProtectDetailsGenerated} + return []string{ + core.AgentConfigChanged, + core.NginxAppProtectDetailsGenerated, + core.NginxConfigValidationPending, + core.NginxConfigApplyFailed, + core.NginxConfigApplySucceeded, + } +} + +func (dps *DataPlaneStatus) updateAgentActivityStatuses(newAgentActivityStatus *proto.AgentActivityStatus) { + log.Tracef("DataplaneStatus: Adding %v to agentActivityStatuses", 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) + } + } + } } func (dps *DataPlaneStatus) sendDataplaneStatus(pipeline core.MessagePipeInterface, forceDetails bool) { @@ -133,6 +190,7 @@ func (dps *DataPlaneStatus) dataplaneStatus(forceDetails bool) *proto.DataplaneS Details: dps.detailsForProcess(processes, forceDetails), Healths: dps.healthForProcess(processes), DataplaneSoftwareDetails: dps.dataplaneSoftwareDetails(), + AgentActivityStatus: dps.agentActivityStatuses, } } diff --git a/src/plugins/dataplane_status_test.go b/src/plugins/dataplane_status_test.go index 496c69449..b5377ff10 100644 --- a/src/plugins/dataplane_status_test.go +++ b/src/plugins/dataplane_status_test.go @@ -18,6 +18,83 @@ import ( ) func TestDataPlaneStatus(t *testing.T) { + tests := []struct { + testName string + message *core.Message + expectedMessage *core.Message + }{ + { + testName: "default status", + message: nil, + expectedMessage: core.NewMessage(core.CommStatus, &proto.Command{ + Meta: nil, + Data: &proto.Command_DataplaneStatus{ + DataplaneStatus: &proto.DataplaneStatus{}, + }, + }), + }, + { + testName: "successful nginx config apply", + message: core.NewMessage(core.NginxConfigApplySucceeded, &proto.AgentActivityStatus{ + Status: &proto.AgentActivityStatus_NginxConfigStatus{ + NginxConfigStatus: &proto.NginxConfigStatus{ + CorrelationId: "123", + Status: proto.NginxConfigStatus_OK, + Message: "config applied", + }, + }, + }), + expectedMessage: core.NewMessage(core.CommStatus, &proto.Command{ + Meta: nil, + Data: &proto.Command_DataplaneStatus{ + DataplaneStatus: &proto.DataplaneStatus{ + AgentActivityStatus: []*proto.AgentActivityStatus{ + { + Status: &proto.AgentActivityStatus_NginxConfigStatus{ + NginxConfigStatus: &proto.NginxConfigStatus{ + CorrelationId: "123", + Status: proto.NginxConfigStatus_OK, + Message: "config applied", + }, + }, + }, + }, + }, + }, + }), + }, + { + testName: "nginx config apply failed", + message: core.NewMessage(core.NginxConfigApplySucceeded, &proto.AgentActivityStatus{ + Status: &proto.AgentActivityStatus_NginxConfigStatus{ + NginxConfigStatus: &proto.NginxConfigStatus{ + CorrelationId: "123", + Status: proto.NginxConfigStatus_ERROR, + Message: "config applied failed", + }, + }, + }), + expectedMessage: core.NewMessage(core.CommStatus, &proto.Command{ + Meta: nil, + Data: &proto.Command_DataplaneStatus{ + DataplaneStatus: &proto.DataplaneStatus{ + AgentActivityStatus: []*proto.AgentActivityStatus{ + { + Status: &proto.AgentActivityStatus_NginxConfigStatus{ + NginxConfigStatus: &proto.NginxConfigStatus{ + CorrelationId: "123", + Status: proto.NginxConfigStatus_ERROR, + Message: "config applied failed", + }, + }, + }, + }, + }, + }, + }), + }, + } + processID := "12345" detailsMap := map[string]*proto.NginxDetails{ processID: { @@ -59,30 +136,30 @@ func TestDataPlaneStatus(t *testing.T) { messagePipe.Run() defer dataPlaneStatus.Close() - // Instance Service - t.Run("returns get response", func(t *testing.T) { - // sleep for 3 seconds - // check messages - // need to mock env - time.Sleep(3 * time.Second) - result := messagePipe.GetProcessedMessages() - - expectedMsg := []string{ - core.CommStatus, - } - assert.GreaterOrEqual(t, len(result), len(expectedMsg)) - for idx, expMsg := range expectedMsg { - message := result[idx] - assert.Equal(t, expMsg, message.Topic()) - if expMsg == core.CommStatus { - cmd := message.Data().(*proto.Command) - dps := cmd.Data.(*proto.Command_DataplaneStatus) - assert.NotNil(t, dps) - assert.NotNil(t, dps.DataplaneStatus.GetHost().GetHostname()) - assert.Len(t, dps.DataplaneStatus.GetDataplaneSoftwareDetails(), 1) + for _, test := range tests { + t.Run(test.testName, func(tt *testing.T) { + if test.message != nil { + messagePipe.Process(test.message) + messagePipe.RunWithoutInit() } - } - }) + + result := messagePipe.GetProcessedMessages() + + message := result[len(result)-1] + assert.Equal(t, test.expectedMessage.Topic(), message.Topic()) + + cmd := message.Data().(*proto.Command) + dps := cmd.Data.(*proto.Command_DataplaneStatus) + + expectedCmd := test.expectedMessage.Data().(*proto.Command) + expectedDps := expectedCmd.Data.(*proto.Command_DataplaneStatus) + + assert.NotNil(t, dps) + assert.NotNil(t, dps.DataplaneStatus.GetHost().GetHostname()) + assert.Len(t, dps.DataplaneStatus.GetDataplaneSoftwareDetails(), 1) + assert.EqualValues(t, expectedDps.DataplaneStatus.GetAgentActivityStatus(), dps.DataplaneStatus.GetAgentActivityStatus()) + }) + } } func TestDPSSyncAgentConfigChange(t *testing.T) { @@ -245,3 +322,42 @@ func TestDPSSyncNAPDetails(t *testing.T) { }) } } + +func TestDataPlaneSubscriptions(t *testing.T) { + expectedSubscriptions := []string{ + core.AgentConfigChanged, + core.NginxAppProtectDetailsGenerated, + core.NginxConfigValidationPending, + core.NginxConfigApplyFailed, + core.NginxConfigApplySucceeded, + } + + processID := "12345" + + binary := tutils.NewMockNginxBinary() + binary.On("GetNginxDetailsMapFromProcesses", mock.Anything).Return(detailsMap) + binary.On("GetNginxIDForProcess", mock.Anything).Return(processID) + binary.On("GetNginxDetailsFromProcess", mock.Anything).Return(detailsMap[processID]) + + env := tutils.NewMockEnvironment() + env.On("Processes", mock.Anything).Return([]core.Process{}) + env.On("NewHostInfo", mock.Anything, mock.Anything, mock.Anything).Return(&proto.HostInfo{ + Hostname: "test-host", + }) + + config := &config.Config{ + Server: config.Server{}, + ConfigDirs: "", + Log: config.LogConfig{}, + TLS: config.TLSConfig{}, + Dataplane: config.Dataplane{ + Status: config.Status{PollInterval: time.Duration(1)}, + }, + AgentMetrics: config.AgentMetrics{}, + Tags: []string{}, + } + + dataPlaneStatus := NewDataPlaneStatus(config, grpc.NewMessageMeta(uuid.New().String()), binary, env, "") + + assert.Equal(t, expectedSubscriptions, dataPlaneStatus.Subscriptions()) +} diff --git a/src/plugins/nginx.go b/src/plugins/nginx.go index 2dabec01f..e22d871ce 100644 --- a/src/plugins/nginx.go +++ b/src/plugins/nginx.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "time" "github.com/gogo/protobuf/types" "github.com/google/uuid" @@ -11,7 +12,9 @@ import ( "github.com/nginx/agent/sdk/v2" "github.com/nginx/agent/sdk/v2/client" + "github.com/nginx/agent/sdk/v2/grpc" + agent_config "github.com/nginx/agent/sdk/v2/agent/config" "github.com/nginx/agent/sdk/v2/proto" "github.com/nginx/agent/v2/src/core" "github.com/nginx/agent/v2/src/core/config" @@ -21,16 +24,21 @@ const ( appProtectMetadataFilePath = "/etc/nms/app_protect_metadata.json" ) +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 + 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 } type ConfigRollbackResponse struct { @@ -47,6 +55,15 @@ type NginxReloadResponse struct { nginxDetails *proto.NginxDetails } +type NginxConfigValidationResponse struct { + err error + correlationId string + nginxDetails *proto.NginxDetails + config *proto.NginxConfig + configApply *sdk.ConfigApply + elapsedTime time.Duration +} + func NewNginx(cmdr client.Commander, nginxBinary core.NginxBinary, env core.Environment, loadedConfig *config.Config) *Nginx { var isNAPEnabled bool if loadedConfig.NginxAppProtect != (config.NginxAppProtect{}) { @@ -55,7 +72,16 @@ func NewNginx(cmdr client.Commander, nginxBinary core.NginxBinary, env core.Envi isConfUploadEnabled := isConfUploadEnabled(loadedConfig) - return &Nginx{nginxBinary: nginxBinary, processes: env.Processes(), env: env, cmdr: cmdr, config: loadedConfig, isNAPEnabled: isNAPEnabled, isConfUploadEnabled: isConfUploadEnabled} + return &Nginx{ + nginxBinary: nginxBinary, + processes: env.Processes(), + env: env, + cmdr: cmdr, + config: loadedConfig, + isNAPEnabled: isNAPEnabled, + isConfUploadEnabled: isConfUploadEnabled, + configApplyStatusChannel: make(chan *proto.Command_NginxConfigResponse, 1), + } } // Init initializes the plugin @@ -95,6 +121,29 @@ func (n *Nginx) Process(message *core.Message) { case core.AgentConfigChanged: // If the agent config on disk changed update this with relevant config info n.syncAgentConfigChange() + case core.NginxConfigValidationSucceeded: + switch response := message.Data().(type) { + case *NginxConfigValidationResponse: + status := n.completeConfigApply(response) + if response.elapsedTime < validationTimeout { + n.configApplyStatusChannel <- status + } + } + case core.NginxConfigValidationFailed: + switch response := message.Data().(type) { + case *NginxConfigValidationResponse: + n.rollbackConfigApply(response) + status := &proto.Command_NginxConfigResponse{ + NginxConfigResponse: &proto.NginxConfigResponse{ + Status: newErrStatus(fmt.Sprintf("Config apply failed (write): " + response.err.Error())).CmdStatus, + Action: proto.NginxConfigAction_APPLY, + ConfigData: response.config.ConfigData, + }, + } + if response.elapsedTime < validationTimeout { + n.configApplyStatusChannel <- status + } + } case core.EnableExtension: switch data := message.Data().(type) { case string: @@ -113,6 +162,9 @@ func (n *Nginx) Subscriptions() []string { core.DataplaneChanged, core.AgentConfigChanged, core.EnableExtension, + core.NginxConfigValidationPending, + core.NginxConfigValidationSucceeded, + core.NginxConfigValidationFailed, } } @@ -203,20 +255,22 @@ func (n *Nginx) processCmd(cmd *proto.Command) { } } -// The applyConfig does the following: -// - Download config -// - Stop file watcher -// - Write the config -// - Valid config -// - Upload the config -// - Start file watcher -// - Reload nginx 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 applied successfully").CmdStatus, + Status: newOKStatus("config apply request successfully processed").CmdStatus, Action: proto.NginxConfigAction_APPLY, ConfigData: cfg.NginxConfig.ConfigData, }, @@ -263,36 +317,77 @@ 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) } - err = n.nginxBinary.ValidateConfig(nginx.NginxId, nginx.ProcessPath, nginx.ConfPath, config, configApply) + go n.validateConfig(nginx, cmd.Meta.MessageId, 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 + // will be removed. + select { + 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) + return status + } +} + +// This function will run a nginx config validation in a separate go routine. If the validation takes less than 15 seconds then the result is returned straight away, +// otherwise nil is returned and the validation continues on in the background until it is complete. The result is always added to the message pipeline for other plugins +// to use. +func (n *Nginx) validateConfig(nginx *proto.NginxDetails, correlationId string, config *proto.NginxConfig, configApply *sdk.ConfigApply) { + start := time.Now() + + err := n.nginxBinary.ValidateConfig(nginx.NginxId, nginx.ProcessPath, nginx.ConfPath, config, configApply) if err == nil { _, err = n.nginxBinary.ReadConfig(nginx.GetConfPath(), config.GetConfigData().GetNginxId(), n.env.GetSystemUUID()) } - if err != nil { - if configApply != nil { - succeeded := true - if rollbackErr := configApply.Rollback(err); rollbackErr != nil { - log.Errorf("Config rollback failed: %v", rollbackErr) - succeeded = false - } + elapsedTime := time.Since(start) + log.Tracef("nginx config validation took %s to complete", elapsedTime) - configRollbackResponse := ConfigRollbackResponse{ - succeeded: succeeded, - correlationId: cmd.Meta.MessageId, - timestamp: types.TimestampNow(), - nginxDetails: nginx, - } - n.messagePipeline.Process(core.NewMessage(core.ConfigRollbackResponse, configRollbackResponse)) + if err != nil { + response := &NginxConfigValidationResponse{ + err: fmt.Errorf("error running nginx -t -c %s:\n %v", nginx.ConfPath, err), + correlationId: correlationId, + nginxDetails: nginx, + config: config, + configApply: configApply, + elapsedTime: elapsedTime, } + n.messagePipeline.Process(core.NewMessage(core.NginxConfigValidationFailed, response)) + } else { + response := &NginxConfigValidationResponse{ + err: nil, + correlationId: correlationId, + nginxDetails: nginx, + config: config, + configApply: configApply, + elapsedTime: elapsedTime, + } + n.messagePipeline.Process(core.NewMessage(core.NginxConfigValidationSucceeded, response)) + } +} - message := fmt.Sprintf("Config apply failed (write): " + err.Error()) - return n.handleErrorStatus(status, message) - } else if configApply != nil { - if err = configApply.Complete(); err != nil { - log.Errorf("Config complete failed: %v", err) +func (n *Nginx) completeConfigApply(response *NginxConfigValidationResponse) *proto.Command_NginxConfigResponse { + nginxConfigStatusMessage := "Config applied successfully" + if response.configApply != nil { + if err := response.configApply.Complete(); err != nil { + nginxConfigStatusMessage = fmt.Sprintf("Config complete failed: %v", err) + log.Errorf(nginxConfigStatusMessage) } } @@ -304,40 +399,111 @@ func (n *Nginx) applyConfig(cmd *proto.Command, cfg *proto.Command_NginxConfig) }, } - err = n.uploadConfig( + err := n.uploadConfig( &proto.ConfigDescriptor{ SystemId: n.env.GetSystemUUID(), - NginxId: config.GetConfigData().GetNginxId(), + NginxId: response.config.GetConfigData().GetNginxId(), }, - cmd.Meta.GetMessageId(), + response.correlationId, ) if err != nil { - uploadResponse.NginxConfigResponse.Status = newErrStatus("config uploaded error: " + err.Error()).CmdStatus + uploadResponse.NginxConfigResponse.Status = newErrStatus("Config uploaded error: " + err.Error()).CmdStatus + nginxConfigStatusMessage = fmt.Sprintf("Config uploaded error: %v", err) + log.Errorf(nginxConfigStatusMessage) } - uploadResponseCommand := newStatusCommand(cmd) + uploadResponseCommand := &proto.Command{Meta: grpc.NewMessageMeta(response.correlationId)} uploadResponseCommand.Data = uploadResponse n.messagePipeline.Process(core.NewMessage(core.CommResponse, uploadResponseCommand)) log.Debug("Enabling file watcher") n.messagePipeline.Process(core.NewMessage(core.FileWatcherEnabled, true)) - reloadErr := n.nginxBinary.Reload(nginx.ProcessId, nginx.ProcessPath) + reloadErr := n.nginxBinary.Reload(response.nginxDetails.ProcessId, response.nginxDetails.ProcessPath) if reloadErr != nil { - status.NginxConfigResponse.Status = newErrStatus("Config apply failed (write): " + reloadErr.Error()).CmdStatus + nginxConfigStatusMessage = fmt.Sprintf("Config apply failed (write): %v", reloadErr) + log.Errorf(nginxConfigStatusMessage) } nginxReloadEventMeta := NginxReloadResponse{ succeeded: reloadErr == nil, - correlationId: cmd.Meta.MessageId, + correlationId: response.correlationId, timestamp: types.TimestampNow(), - nginxDetails: nginx, + nginxDetails: response.nginxDetails, } + n.messagePipeline.Process(core.NewMessage(core.NginxReloadComplete, nginxReloadEventMeta)) + + agentActivityStatus := &proto.AgentActivityStatus{ + Status: &proto.AgentActivityStatus_NginxConfigStatus{ + NginxConfigStatus: &proto.NginxConfigStatus{ + CorrelationId: response.correlationId, + Status: proto.NginxConfigStatus_OK, + Message: nginxConfigStatusMessage, + }, + }, + } + + n.messagePipeline.Process(core.NewMessage(core.NginxConfigApplySucceeded, agentActivityStatus)) + + status := &proto.Command_NginxConfigResponse{ + NginxConfigResponse: &proto.NginxConfigResponse{ + Status: newOKStatus("config apply request successfully processed").CmdStatus, + Action: proto.NginxConfigAction_APPLY, + ConfigData: response.config.ConfigData, + }, + } + + if agentActivityStatus.GetNginxConfigStatus().GetStatus() == proto.NginxConfigStatus_ERROR { + status.NginxConfigResponse.Status = newErrStatus(agentActivityStatus.GetNginxConfigStatus().GetMessage()).CmdStatus + } else { + status.NginxConfigResponse.Status = newOKStatus(agentActivityStatus.GetNginxConfigStatus().GetMessage()).CmdStatus + } + log.Debug("Config Apply Complete") + return status } +func (n *Nginx) rollbackConfigApply(response *NginxConfigValidationResponse) { + nginxConfigStatusMessage := fmt.Sprintf("Config apply failed (write): %v", response.err.Error()) + log.Error(nginxConfigStatusMessage) + + if response.configApply != nil { + succeeded := true + + if rollbackErr := response.configApply.Rollback(response.err); rollbackErr != nil { + nginxConfigStatusMessage := fmt.Sprintf("Config rollback failed: %v", rollbackErr) + log.Error(nginxConfigStatusMessage) + succeeded = false + } + + configRollbackResponse := ConfigRollbackResponse{ + succeeded: succeeded, + correlationId: response.correlationId, + timestamp: types.TimestampNow(), + nginxDetails: response.nginxDetails, + } + + n.messagePipeline.Process(core.NewMessage(core.ConfigRollbackResponse, configRollbackResponse)) + + agentActivityStatus := &proto.AgentActivityStatus{ + Status: &proto.AgentActivityStatus_NginxConfigStatus{ + NginxConfigStatus: &proto.NginxConfigStatus{ + CorrelationId: response.correlationId, + Status: proto.NginxConfigStatus_ERROR, + Message: nginxConfigStatusMessage, + }, + }, + } + + n.messagePipeline.Process(core.NewMessage(core.NginxConfigApplyFailed, agentActivityStatus)) + } + + log.Debug("Enabling file watcher") + n.messagePipeline.Process(core.NewMessage(core.FileWatcherEnabled, true)) +} + func (n *Nginx) handleErrorStatus(status *proto.Command_NginxConfigResponse, message string) *proto.Command_NginxConfigResponse { status.NginxConfigResponse.Status = newErrStatus(message).CmdStatus @@ -395,7 +561,7 @@ func (n *Nginx) syncAgentConfigChange() { func isConfUploadEnabled(conf *config.Config) bool { for _, feature := range conf.Features { - if feature == config.FeatureNginxConfig { + if feature == agent_config.FeatureNginxConfig { return true } } diff --git a/src/plugins/nginx_test.go b/src/plugins/nginx_test.go index d8b37c14f..779386755 100644 --- a/src/plugins/nginx_test.go +++ b/src/plugins/nginx_test.go @@ -2,9 +2,11 @@ package plugins import ( "context" + "errors" "fmt" "io/ioutil" "testing" + "time" "github.com/google/uuid" "github.com/stretchr/testify/assert" @@ -15,6 +17,7 @@ import ( "github.com/nginx/agent/sdk/v2/grpc" "github.com/nginx/agent/sdk/v2/proto" + 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" @@ -89,7 +92,8 @@ var ( }`) ) -func TestNginx_Config(t *testing.T) { +func TestNginxConfigApply(t *testing.T) { + validationTimeout = 0 * time.Millisecond t.Parallel() tests := []struct { @@ -118,11 +122,10 @@ func TestNginx_Config(t *testing.T) { core.CommNginxConfig, core.NginxPluginConfigured, core.NginxInstancesFound, + core.NginxConfigValidationPending, core.FileWatcherEnabled, core.CommResponse, - core.FileWatcherEnabled, - core.NginxReloadComplete, - core.CommResponse, + core.NginxConfigValidationSucceeded, }, }, { @@ -147,11 +150,10 @@ func TestNginx_Config(t *testing.T) { core.CommNginxConfig, core.NginxPluginConfigured, core.NginxInstancesFound, + core.NginxConfigValidationPending, core.FileWatcherEnabled, core.CommResponse, - core.FileWatcherEnabled, - core.NginxReloadComplete, - core.CommResponse, + core.NginxConfigValidationSucceeded, }, }, { @@ -176,11 +178,10 @@ func TestNginx_Config(t *testing.T) { core.CommNginxConfig, core.NginxPluginConfigured, core.NginxInstancesFound, + core.NginxConfigValidationPending, core.FileWatcherEnabled, core.CommResponse, - core.FileWatcherEnabled, - core.NginxReloadComplete, - core.CommResponse, + core.NginxConfigValidationSucceeded, }, }, } @@ -210,7 +211,7 @@ func TestNginx_Config(t *testing.T) { err = ioutil.WriteFile(tempConf.Name(), fourth, 0644) assert.NoError(t, err) - ctx, cancel := context.WithCancel(context.Background()) + ctx := context.TODO() env := tutils.GetMockEnvWithProcess() allowedDirectoriesMap := map[string]struct{}{dir: {}} @@ -220,30 +221,28 @@ func TestNginx_Config(t *testing.T) { binary := tutils.NewMockNginxBinary() binary.On("WriteConfig", mock.Anything).Return(config, nil) - binary.On("ReadConfig", mock.Anything, mock.Anything, mock.Anything).Return(&proto.NginxConfig{}, nil) binary.On("ValidateConfig", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) + binary.On("ReadConfig", mock.Anything, mock.Anything, mock.Anything).Return(&proto.NginxConfig{}, nil) binary.On("GetNginxDetailsByID", "12345").Return(tutils.GetDetailsMap()["12345"]) binary.On("UpdateNginxDetailsFromProcesses", env.Processes()) binary.On("GetNginxDetailsMapFromProcesses", env.Processes()).Return((tutils.GetDetailsMap())) - binary.On("Reload", mock.Anything, mock.Anything) commandClient := tutils.GetMockCommandClient(test.config) - pluginUnderTest := NewNginx(commandClient, binary, env, &loadedConfig.Config{Features: []string{loadedConfig.FeatureNginxConfig}}) + pluginUnderTest := NewNginx(commandClient, binary, env, &loadedConfig.Config{Features: []string{agent_config.FeatureNginxConfig}}) messagePipe := core.SetupMockMessagePipe(t, ctx, pluginUnderTest) messagePipe.Process(core.NewMessage(core.CommNginxConfig, cmd)) messagePipe.Run() - binary.AssertExpectations(tt) - env.AssertExpectations(tt) - cancel() + assert.Eventually( + tt, + func() bool { return len(messagePipe.GetProcessedMessages()) != len(test.msgTopics) }, + time.Duration(5*time.Second), + 3*time.Millisecond, + ) - processedMessages := messagePipe.GetProcessedMessages() - if len(processedMessages) != len(test.msgTopics) { - tt.Fatalf("expected %d messages, received %d: %+v", len(test.msgTopics), len(processedMessages), processedMessages) - } - for idx, msg := range processedMessages { + for idx, msg := range messagePipe.GetProcessedMessages() { if test.msgTopics[idx] != msg.Topic() { tt.Errorf("unexpected message topic: %s :: should have been: %s", msg.Topic(), test.msgTopics[idx]) } @@ -297,7 +296,7 @@ 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{loadedConfig.FeatureNginxConfig}}) + pluginUnderTest := NewNginx(cmdr, binary, env, &loadedConfig.Config{Features: []string{agent_config.FeatureNginxConfig}}) messagePipe := core.SetupMockMessagePipe(t, context.Background(), pluginUnderTest) pluginUnderTest.Init(messagePipe) @@ -401,7 +400,7 @@ func TestNginx_Process_NginxConfigUpload(t *testing.T) { env := tutils.GetMockEnvWithProcess() - pluginUnderTest := NewNginx(cmdr, binary, env, &loadedConfig.Config{Features: []string{loadedConfig.FeatureNginxConfig}}) + pluginUnderTest := NewNginx(cmdr, binary, env, &loadedConfig.Config{Features: []string{agent_config.FeatureNginxConfig}}) pluginUnderTest.Process(core.NewMessage(core.NginxConfigUpload, configDesc)) binary.AssertExpectations(t) @@ -419,6 +418,9 @@ func TestNginx_Subscriptions(t *testing.T) { core.DataplaneChanged, core.AgentConfigChanged, core.EnableExtension, + core.NginxConfigValidationPending, + core.NginxConfigValidationSucceeded, + core.NginxConfigValidationFailed, } pluginUnderTest := NewNginx(nil, nil, tutils.GetMockEnvWithProcess(), &loadedConfig.Config{}) @@ -430,3 +432,231 @@ func TestNginx_Info(t *testing.T) { assert.Equal(t, "NginxBinary", pluginUnderTest.Info().Name()) } + +func TestNginx_validateConfig(t *testing.T) { + tests := []struct { + name string + validationResult error + expectedTopic string + expectedError error + }{ + { + name: "successful validation", + validationResult: nil, + expectedTopic: core.NginxConfigValidationSucceeded, + }, + { + name: "failed validation", + validationResult: errors.New("failure"), + expectedTopic: core.NginxConfigValidationFailed, + }, + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + + env := tutils.GetMockEnvWithProcess() + binary := tutils.NewMockNginxBinary() + binary.On("ValidateConfig", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(test.validationResult) + 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()) + + pluginUnderTest := NewNginx(&tutils.MockCommandClient{}, binary, env, &loadedConfig.Config{Features: []string{agent_config.FeatureNginxConfig}}) + + messagePipe := core.SetupMockMessagePipe(t, context.TODO(), pluginUnderTest) + messagePipe.Run() + + pluginUnderTest.validateConfig(&proto.NginxDetails{}, "123", &proto.NginxConfig{}, &sdk.ConfigApply{}) + + assert.Eventually( + t, + func() bool { return len(messagePipe.GetMessages()) == 1 }, + time.Duration(2*time.Second), + 3*time.Millisecond, + ) + + assert.Equal(t, test.expectedTopic, messagePipe.GetMessages()[0].Topic()) + assert.Equal(t, "123", messagePipe.GetMessages()[0].Data().(*NginxConfigValidationResponse).correlationId) + if test.validationResult == nil { + assert.Nil(t, messagePipe.GetMessages()[0].Data().(*NginxConfigValidationResponse).err) + } else { + assert.NotNil(t, messagePipe.GetMessages()[0].Data().(*NginxConfigValidationResponse).err) + } + assert.Greater(t, messagePipe.GetMessages()[0].Data().(*NginxConfigValidationResponse).elapsedTime, 0*time.Second) + }) + } +} + +func TestNginx_completeConfigApply(t *testing.T) { + expectedTopics := []string{ + core.NginxConfigValidationSucceeded, + core.NginxPluginConfigured, + core.NginxInstancesFound, + core.CommResponse, + core.FileWatcherEnabled, + core.NginxReloadComplete, + core.NginxConfigApplySucceeded, + } + + env := tutils.GetMockEnvWithProcess() + env.On("GetSystemUUID").Return("456") + + binary := tutils.NewMockNginxBinary() + binary.On("uploadConfig", mock.Anything, mock.Anything).Return(nil) + binary.On("GetNginxDetailsByID", "12345").Return(tutils.GetDetailsMap()["12345"]) + binary.On("ReadConfig", mock.Anything, mock.Anything, mock.Anything).Return(&proto.NginxConfig{}, nil) + binary.On("UpdateNginxDetailsFromProcesses", env.Processes()) + binary.On("GetNginxDetailsMapFromProcesses", env.Processes()).Return((tutils.GetDetailsMap())) + binary.On("Reload", mock.Anything, mock.Anything) + + commandClient := tutils.GetMockCommandClient( + &proto.NginxConfig{ + Action: proto.NginxConfigAction_APPLY, + ConfigData: &proto.ConfigDescriptor{ + NginxId: "12345", + Checksum: "2314365", + }, + Zconfig: &proto.ZippedFile{ + Contents: first, + Checksum: checksum.Checksum(first), + RootDirectory: "nginx.conf", + }, + Zaux: &proto.ZippedFile{}, + AccessLogs: &proto.AccessLogs{}, + ErrorLogs: &proto.ErrorLogs{}, + Ssl: &proto.SslCertificates{}, + DirectoryMap: &proto.DirectoryMap{}, + }, + ) + + pluginUnderTest := NewNginx(commandClient, binary, env, &loadedConfig.Config{Features: []string{agent_config.FeatureNginxConfig}}) + + dir := t.TempDir() + tempConf, err := ioutil.TempFile(dir, "nginx.conf") + assert.NoError(t, err) + allowedDirectoriesMap := map[string]struct{}{dir: {}} + configApply, err := sdk.NewConfigApply(tempConf.Name(), allowedDirectoriesMap) + + response := &NginxConfigValidationResponse{ + err: nil, + correlationId: "123", + nginxDetails: &proto.NginxDetails{ + NginxId: "12345", + ProcessId: "123456", + ProcessPath: "/var/test/", + }, + config: &proto.NginxConfig{ + Action: proto.NginxConfigAction_APPLY, + ConfigData: &proto.ConfigDescriptor{ + SystemId: "456", + NginxId: "12345", + Checksum: "2314365", + }, + }, + configApply: configApply, + } + + messagePipe := core.SetupMockMessagePipe(t, context.TODO(), pluginUnderTest) + messagePipe.Process(core.NewMessage(core.NginxConfigValidationSucceeded, response)) + messagePipe.Run() + + assert.Eventually( + t, + func() bool { return len(messagePipe.GetProcessedMessages()) == len(expectedTopics) }, + time.Duration(2*time.Second), + 3*time.Millisecond, + ) + + for idx, msg := range messagePipe.GetProcessedMessages() { + if expectedTopics[idx] != msg.Topic() { + t.Errorf("unexpected message topic: %s :: should have been: %s", msg.Topic(), expectedTopics[idx]) + } + } +} + +func TestNginx_rollbackConfigApply(t *testing.T) { + expectedTopics := []string{ + core.NginxConfigValidationFailed, + core.NginxPluginConfigured, + core.NginxInstancesFound, + core.ConfigRollbackResponse, + core.NginxConfigApplyFailed, + core.FileWatcherEnabled, + } + + env := tutils.GetMockEnvWithProcess() + env.On("GetSystemUUID").Return("456") + + binary := tutils.NewMockNginxBinary() + binary.On("uploadConfig", mock.Anything, mock.Anything).Return(nil) + binary.On("GetNginxDetailsByID", "12345").Return(tutils.GetDetailsMap()["12345"]) + binary.On("ReadConfig", mock.Anything, mock.Anything, mock.Anything).Return(&proto.NginxConfig{}, nil) + binary.On("UpdateNginxDetailsFromProcesses", env.Processes()) + binary.On("GetNginxDetailsMapFromProcesses", env.Processes()).Return((tutils.GetDetailsMap())) + binary.On("Reload", mock.Anything, mock.Anything) + + commandClient := tutils.GetMockCommandClient( + &proto.NginxConfig{ + Action: proto.NginxConfigAction_APPLY, + ConfigData: &proto.ConfigDescriptor{ + NginxId: "12345", + Checksum: "2314365", + }, + Zconfig: &proto.ZippedFile{ + Contents: first, + Checksum: checksum.Checksum(first), + RootDirectory: "nginx.conf", + }, + Zaux: &proto.ZippedFile{}, + AccessLogs: &proto.AccessLogs{}, + ErrorLogs: &proto.ErrorLogs{}, + Ssl: &proto.SslCertificates{}, + DirectoryMap: &proto.DirectoryMap{}, + }, + ) + + pluginUnderTest := NewNginx(commandClient, binary, env, &loadedConfig.Config{Features: []string{agent_config.FeatureNginxConfig}}) + + dir := t.TempDir() + tempConf, err := ioutil.TempFile(dir, "nginx.conf") + assert.NoError(t, err) + allowedDirectoriesMap := map[string]struct{}{dir: {}} + configApply, err := sdk.NewConfigApply(tempConf.Name(), allowedDirectoriesMap) + + response := &NginxConfigValidationResponse{ + err: errors.New("Failure"), + correlationId: "123", + nginxDetails: &proto.NginxDetails{ + NginxId: "12345", + ProcessId: "123456", + ProcessPath: "/var/test/", + }, + config: &proto.NginxConfig{ + Action: proto.NginxConfigAction_APPLY, + ConfigData: &proto.ConfigDescriptor{ + SystemId: "456", + NginxId: "12345", + Checksum: "2314365", + }, + }, + configApply: configApply, + } + + messagePipe := core.SetupMockMessagePipe(t, context.TODO(), pluginUnderTest) + messagePipe.Process(core.NewMessage(core.NginxConfigValidationFailed, response)) + messagePipe.Run() + + assert.Eventually( + t, + func() bool { return len(messagePipe.GetProcessedMessages()) == len(expectedTopics) }, + time.Duration(2*time.Second), + 1*time.Millisecond, + ) + + for idx, msg := range messagePipe.GetProcessedMessages() { + if expectedTopics[idx] != msg.Topic() { + t.Errorf("unexpected message topic: %s :: should have been: %s", msg.Topic(), expectedTopics[idx]) + } + } +} diff --git a/src/plugins/registration.go b/src/plugins/registration.go index 71edbb816..5e170bce5 100644 --- a/src/plugins/registration.go +++ b/src/plugins/registration.go @@ -131,6 +131,12 @@ func (r *OneTimeRegistration) registerAgent() { InstanceGroup: r.config.InstanceGroup, Updated: updated, SystemUid: r.env.GetSystemUUID(), + AgentDetails: &proto.AgentDetails{ + Features: r.config.Features, + Extensions: r.config.Extensions, + Tags: *r.tags, + Alias: "", + }, }, Details: details, DataplaneSoftwareDetails: r.dataplaneSoftwareDetailsSlice(), diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/config/config_helpers.go b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/config/config_helpers.go new file mode 100644 index 000000000..62e6492b5 --- /dev/null +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/agent/config/config_helpers.go @@ -0,0 +1,35 @@ +package config + +const ( + KeyDelimiter = "_" + + // viper keys used in config + FeaturesKey = "features" + FeatureRegistration = FeaturesKey + KeyDelimiter + "registration" + FeatureNginxConfig = FeaturesKey + KeyDelimiter + "nginx-config" + FeatureNginxConfigAsync = FeaturesKey + KeyDelimiter + "nginx-config-async" + FeatureNginxSSLConfig = FeaturesKey + KeyDelimiter + "nginx-ssl-config" + FeatureNginxCounting = FeaturesKey + KeyDelimiter + "nginx-counting" + FeatureMetrics = FeaturesKey + KeyDelimiter + "metrics" + FeatureMetricsThrottle = FeaturesKey + KeyDelimiter + "metrics-throttle" + FeatureDataPlaneStatus = FeaturesKey + KeyDelimiter + "dataplane-status" + FeatureProcessWatcher = FeaturesKey + KeyDelimiter + "process-watcher" + FeatureFileWatcher = FeaturesKey + KeyDelimiter + "file-watcher" + FeatureActivityEvents = FeaturesKey + KeyDelimiter + "activity-events" +) + +func GetDefaultFeatures() []string { + return []string{ + FeatureRegistration, + FeatureNginxConfig, + FeatureNginxSSLConfig, + FeatureNginxCounting, + FeatureNginxConfigAsync, + FeatureMetrics, + FeatureMetricsThrottle, + FeatureDataPlaneStatus, + FeatureProcessWatcher, + FeatureFileWatcher, + FeatureActivityEvents, + } +} diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/agent.pb.go b/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/agent.pb.go index 61affae6b..f0335e02e 100644 --- a/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/agent.pb.go +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/agent.pb.go @@ -553,6 +553,7 @@ type AgentMeta struct { InstanceGroup string `protobuf:"bytes,5,opt,name=instance_group,json=instanceGroup,proto3" json:"instance_group"` Updated *types.Timestamp `protobuf:"bytes,6,opt,name=updated,proto3" json:"updated"` SystemUid string `protobuf:"bytes,7,opt,name=system_uid,json=systemUid,proto3" json:"system_uid"` + AgentDetails *AgentDetails `protobuf:"bytes,8,opt,name=agent_details,json=agentDetails,proto3" json:"agent_details"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -633,6 +634,13 @@ func (m *AgentMeta) GetSystemUid() string { return "" } +func (m *AgentMeta) GetAgentDetails() *AgentDetails { + if m != nil { + return m.AgentDetails + } + return nil +} + func init() { proto.RegisterEnum("f5.nginx.agent.sdk.AgentConnectStatus_StatusCode", AgentConnectStatus_StatusCode_name, AgentConnectStatus_StatusCode_value) proto.RegisterEnum("f5.nginx.agent.sdk.AgentLogging_Level", AgentLogging_Level_name, AgentLogging_Level_value) @@ -649,74 +657,75 @@ func init() { func init() { proto.RegisterFile("agent.proto", fileDescriptor_56ede974c0020f77) } var fileDescriptor_56ede974c0020f77 = []byte{ - // 1060 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xcd, 0x6e, 0x23, 0x45, - 0x10, 0xde, 0xf1, 0x4f, 0x6c, 0x97, 0xb3, 0xd9, 0x51, 0xef, 0x0a, 0xbc, 0x66, 0xc9, 0x58, 0x16, - 0x2c, 0x46, 0x82, 0x31, 0x78, 0x85, 0x10, 0x2c, 0x17, 0x3b, 0xf6, 0x66, 0x37, 0x1b, 0x6c, 0xd4, - 0x71, 0xb4, 0x12, 0x97, 0x51, 0xc7, 0xd3, 0x9e, 0x1d, 0xe2, 0x99, 0x36, 0xd3, 0xed, 0xe0, 0xec, - 0x23, 0xf0, 0x22, 0x5c, 0x78, 0x00, 0x1e, 0x80, 0x03, 0x47, 0x9e, 0xc0, 0x42, 0x39, 0xa1, 0x39, - 0x73, 0xe1, 0x86, 0xfa, 0x67, 0x12, 0x87, 0xfc, 0xc0, 0xa5, 0xbb, 0xea, 0xeb, 0xaa, 0xea, 0xaa, - 0xea, 0xaa, 0x9a, 0x81, 0x2a, 0x09, 0x68, 0x2c, 0xdc, 0x79, 0xc2, 0x04, 0x43, 0x68, 0xfa, 0x99, - 0x1b, 0x07, 0x61, 0xbc, 0x74, 0x35, 0xca, 0xfd, 0xe3, 0x3a, 0x04, 0x2c, 0x60, 0xfa, 0xbc, 0x0e, - 0xaf, 0x19, 0x37, 0xb2, 0xf5, 0xcd, 0x09, 0x8b, 0xa7, 0x61, 0x60, 0xb8, 0xaa, 0x56, 0xd3, 0x8c, - 0x13, 0x30, 0x16, 0xcc, 0x68, 0x5b, 0x71, 0x47, 0x8b, 0x69, 0x5b, 0x84, 0x11, 0xe5, 0x82, 0x44, - 0x73, 0x23, 0xf0, 0xd0, 0x9f, 0x7b, 0x9c, 0x4d, 0xc5, 0x0f, 0x24, 0xa1, 0x9e, 0x4f, 0x05, 0x09, - 0x67, 0x5c, 0x1f, 0x35, 0xff, 0xca, 0xc1, 0xfd, 0xae, 0xbc, 0x7c, 0x87, 0xc5, 0x31, 0x9d, 0x08, - 0x4c, 0xbf, 0x5f, 0x50, 0x2e, 0xd0, 0x53, 0x28, 0x44, 0x54, 0x90, 0x5a, 0xae, 0x61, 0xb5, 0xaa, - 0x9d, 0x77, 0xdd, 0xab, 0x9e, 0xba, 0x4a, 0xed, 0x6b, 0x2a, 0x48, 0xaf, 0x9c, 0xae, 0x1c, 0x25, - 0x8e, 0xd5, 0x8a, 0x76, 0xa1, 0x64, 0x6e, 0xa9, 0xe5, 0x1b, 0xf9, 0x56, 0xb5, 0xd3, 0xb8, 0x4e, - 0x7f, 0x28, 0xf9, 0xbe, 0x96, 0xeb, 0x55, 0xd3, 0x95, 0x93, 0x29, 0xe1, 0x8c, 0x40, 0x5f, 0x42, - 0x41, 0xa6, 0xa0, 0x56, 0x50, 0x5e, 0x3c, 0xba, 0xce, 0xca, 0x73, 0xc6, 0xc5, 0x8b, 0x78, 0xca, - 0xb4, 0x13, 0x52, 0x1a, 0xab, 0x15, 0xfd, 0x68, 0x41, 0xdd, 0x27, 0x82, 0xcc, 0x67, 0x24, 0xa6, - 0x57, 0xc2, 0xaf, 0x15, 0x95, 0x63, 0x1f, 0x5d, 0x67, 0xb2, 0x9f, 0x69, 0x1d, 0x18, 0xa5, 0xcc, - 0xc9, 0xed, 0x74, 0xe5, 0xdc, 0x62, 0x13, 0xd7, 0xfc, 0x1b, 0x34, 0xf7, 0x0a, 0x65, 0xcb, 0xce, - 0xe1, 0x72, 0xe8, 0xd3, 0x58, 0x84, 0xe2, 0xb4, 0xf9, 0x73, 0x0e, 0xd0, 0x7a, 0xda, 0x0f, 0x04, - 0x11, 0x0b, 0x8e, 0x8e, 0x00, 0xb8, 0xa2, 0x76, 0x98, 0x4f, 0x6b, 0x56, 0xc3, 0x6a, 0x6d, 0x75, - 0x3e, 0xbd, 0x31, 0xf7, 0x97, 0x74, 0xdd, 0x83, 0x73, 0xc5, 0xde, 0xbd, 0x74, 0xe5, 0x54, 0xb5, - 0x21, 0x6f, 0xc2, 0x7c, 0x8a, 0xd7, 0xac, 0xa2, 0xf7, 0xa1, 0x14, 0x51, 0xce, 0x49, 0x40, 0xd5, - 0xe3, 0x56, 0x74, 0xea, 0x0d, 0x84, 0x33, 0x02, 0x39, 0x50, 0xa4, 0x49, 0xc2, 0x92, 0x5a, 0x5e, - 0x09, 0x55, 0xd2, 0x95, 0xa3, 0x01, 0xac, 0xb7, 0xe6, 0x77, 0x00, 0x17, 0x57, 0xa2, 0xfb, 0x70, - 0x6f, 0x67, 0x34, 0x1c, 0x0e, 0x76, 0xc6, 0xde, 0xe1, 0xf0, 0xe5, 0x70, 0xf4, 0x6a, 0x68, 0xdf, - 0x41, 0x5b, 0x00, 0x19, 0x38, 0x7a, 0x69, 0x5b, 0xa8, 0x0e, 0x6f, 0x65, 0x3c, 0x1e, 0xec, 0x0d, - 0x76, 0xc6, 0x83, 0xbe, 0x37, 0x1a, 0x3f, 0x1f, 0x60, 0x3b, 0x87, 0xde, 0x81, 0xb7, 0xaf, 0x9c, - 0xf5, 0x0f, 0xbf, 0xf1, 0x5e, 0xf4, 0xed, 0x7c, 0xf3, 0x17, 0x0b, 0x1e, 0x5c, 0xae, 0x52, 0x3e, - 0x67, 0x31, 0xa7, 0x68, 0x0c, 0x9b, 0x2a, 0x29, 0x9e, 0xee, 0x0e, 0x95, 0xb2, 0x6a, 0xc7, 0xb9, - 0x2d, 0x65, 0xd3, 0x30, 0xe8, 0xd9, 0xe9, 0xca, 0xb9, 0xa4, 0x88, 0x75, 0x5f, 0xea, 0x63, 0xb4, - 0x07, 0x1b, 0x3a, 0x61, 0xa6, 0xfc, 0x1f, 0xff, 0xbf, 0x27, 0xe8, 0x41, 0xba, 0x72, 0x8c, 0x26, - 0x36, 0x7b, 0xf3, 0xc1, 0xc5, 0x43, 0xcb, 0x7b, 0x74, 0x7b, 0x35, 0xff, 0xb4, 0xa0, 0xba, 0x06, - 0xaf, 0x77, 0x8c, 0x0e, 0xa1, 0x71, 0xe3, 0x95, 0xb7, 0x77, 0xcc, 0x2e, 0x94, 0x66, 0x2c, 0x08, - 0x68, 0x92, 0xf9, 0x7e, 0xb3, 0xa1, 0x7d, 0x16, 0x04, 0x61, 0x1c, 0x68, 0x43, 0x46, 0x09, 0x67, - 0x84, 0x34, 0xa4, 0x53, 0xc3, 0x55, 0x05, 0xdc, 0x60, 0x28, 0x8b, 0x6a, 0xce, 0x12, 0xa1, 0x0d, - 0x19, 0x25, 0x9c, 0x11, 0xcd, 0x9f, 0x2c, 0xd8, 0x5c, 0x77, 0x1c, 0xb5, 0xa0, 0x3c, 0xa5, 0x44, - 0x2c, 0x12, 0x2a, 0x83, 0xcd, 0xb7, 0x2a, 0xbd, 0xcd, 0x74, 0xe5, 0x9c, 0x63, 0xf8, 0x9c, 0x42, - 0x2e, 0x00, 0x5d, 0x0a, 0x1a, 0xf3, 0x90, 0xc5, 0x32, 0x1e, 0x29, 0xbb, 0x95, 0xae, 0x9c, 0x35, - 0x14, 0xaf, 0xd1, 0xe8, 0x11, 0x14, 0x04, 0x09, 0xf4, 0xd0, 0xa9, 0xe8, 0x81, 0x20, 0x79, 0xac, - 0x56, 0x59, 0xd1, 0x64, 0x16, 0x12, 0xae, 0xa6, 0x89, 0xa9, 0x68, 0x05, 0x60, 0xbd, 0x35, 0xff, - 0xce, 0x19, 0x4f, 0x4d, 0x66, 0xd0, 0x2e, 0x14, 0x67, 0xf4, 0x84, 0xce, 0x4c, 0x27, 0x3e, 0xfe, - 0xaf, 0x54, 0xba, 0xfb, 0x52, 0x5a, 0x5b, 0x56, 0x8a, 0x58, 0x6f, 0xe8, 0x21, 0xe4, 0xfd, 0x30, - 0x31, 0xfd, 0x56, 0x4a, 0x57, 0x8e, 0x64, 0xb1, 0x5c, 0xa4, 0xcf, 0xd3, 0x70, 0x46, 0x4d, 0x9b, - 0x29, 0x9f, 0x25, 0x8f, 0xd5, 0x8a, 0x3e, 0x80, 0x72, 0x44, 0x96, 0x1e, 0x0f, 0xdf, 0x50, 0xe5, - 0xf6, 0x5d, 0x9d, 0xab, 0x0c, 0xc3, 0xa5, 0x88, 0x2c, 0x0f, 0xc2, 0x37, 0x14, 0x7d, 0x02, 0x55, - 0x09, 0x1e, 0x91, 0xc9, 0xf1, 0x62, 0x2e, 0xa7, 0x9b, 0x94, 0x55, 0x73, 0x60, 0x0d, 0xc6, 0x10, - 0x91, 0x65, 0x4f, 0xd3, 0xe8, 0x3d, 0x90, 0xca, 0x9e, 0x9c, 0x03, 0x1b, 0x4a, 0x5a, 0xcf, 0x01, - 0x0d, 0xe1, 0x8d, 0x88, 0x2c, 0xbb, 0x01, 0x95, 0x8f, 0x35, 0x61, 0xd1, 0x3c, 0xa1, 0x9c, 0xd7, - 0x4a, 0x0d, 0xab, 0x55, 0xd6, 0x0e, 0x64, 0x18, 0x3e, 0xa7, 0x9a, 0x5f, 0x41, 0x51, 0x85, 0x8f, - 0xca, 0x50, 0x78, 0x31, 0x7c, 0x36, 0xb2, 0xef, 0xa0, 0x0a, 0x14, 0xfb, 0x83, 0xde, 0xe1, 0xae, - 0x6d, 0x49, 0xf0, 0x55, 0x17, 0x0f, 0xed, 0x9c, 0x04, 0x07, 0x18, 0x8f, 0xb0, 0x9d, 0x97, 0xe4, - 0xb3, 0xee, 0xb8, 0xbb, 0x6f, 0x17, 0x9a, 0xbf, 0xe6, 0xa0, 0x72, 0xfe, 0x41, 0x91, 0x33, 0xea, - 0x84, 0x26, 0xf2, 0x51, 0x55, 0xea, 0xcd, 0x8c, 0x32, 0x10, 0xce, 0x08, 0xf4, 0x04, 0x36, 0xfd, - 0x90, 0xcf, 0x67, 0xe4, 0xd4, 0x8b, 0x49, 0x94, 0xcd, 0x33, 0xd5, 0xdc, 0xeb, 0x38, 0xae, 0x1a, - 0x6e, 0x48, 0x22, 0x2a, 0xdf, 0x42, 0x90, 0xc0, 0xd4, 0x88, 0x7a, 0x0b, 0x41, 0x02, 0x2c, 0x17, - 0xf4, 0x05, 0x6c, 0x85, 0x31, 0x17, 0x24, 0x9e, 0x50, 0x2f, 0x48, 0xd8, 0x62, 0xae, 0xf2, 0x58, - 0xe9, 0xa1, 0x74, 0xe5, 0xfc, 0xeb, 0x04, 0xdf, 0xcd, 0xf8, 0x5d, 0xc9, 0xa2, 0x2e, 0x94, 0x16, - 0x73, 0x9f, 0x08, 0xea, 0xab, 0x6c, 0x56, 0x3b, 0x75, 0x57, 0x7f, 0x95, 0xdd, 0xec, 0xab, 0xec, - 0x8e, 0xb3, 0xaf, 0xb2, 0x8e, 0xc6, 0x88, 0xe3, 0x8c, 0x40, 0x1f, 0x03, 0xf0, 0x53, 0x2e, 0x68, - 0xe4, 0x2d, 0x42, 0x5f, 0x25, 0xdb, 0x54, 0xfb, 0x05, 0x8a, 0x2b, 0x9a, 0x3e, 0x0c, 0xfd, 0xbd, - 0x42, 0xb9, 0x60, 0x17, 0x2f, 0xdc, 0x50, 0x91, 0xf6, 0x3e, 0xff, 0xed, 0x6c, 0xdb, 0xfa, 0xfd, - 0x6c, 0xdb, 0xfa, 0xe3, 0x6c, 0xdb, 0xfa, 0xf6, 0xc3, 0x20, 0x14, 0xaf, 0x17, 0x47, 0xee, 0x84, - 0x45, 0x6d, 0x55, 0xb7, 0x6d, 0x55, 0xb7, 0x6d, 0xee, 0x1f, 0xb7, 0x4f, 0x3a, 0xfa, 0x7f, 0xe1, - 0xa9, 0xf6, 0x6f, 0x43, 0x6d, 0x4f, 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0x02, 0x48, 0xb6, 0x2c, - 0xa0, 0x08, 0x00, 0x00, + // 1081 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xcd, 0x72, 0x1b, 0x45, + 0x10, 0xce, 0xea, 0xc7, 0x92, 0x5a, 0xb6, 0xb3, 0x4c, 0x52, 0xa0, 0x88, 0xe0, 0x55, 0xa9, 0x20, + 0x88, 0x2a, 0x58, 0x81, 0x52, 0x14, 0x05, 0xe1, 0x22, 0x59, 0x8a, 0x63, 0xc7, 0x48, 0xd4, 0x58, + 0xae, 0x50, 0x5c, 0xb6, 0xc6, 0xda, 0xd1, 0x66, 0xb1, 0x76, 0x57, 0xec, 0x8c, 0x8c, 0x9c, 0x47, + 0xe0, 0x21, 0xb8, 0x72, 0xe1, 0x01, 0x78, 0x04, 0x8e, 0x3c, 0xc1, 0x16, 0xe5, 0x13, 0xb5, 0x67, + 0x2e, 0xdc, 0xa8, 0xf9, 0x59, 0x5b, 0xc6, 0x3f, 0xc9, 0x65, 0xb6, 0xfb, 0x9b, 0xee, 0x9e, 0x9e, + 0x6f, 0xa6, 0x7b, 0x16, 0xaa, 0xc4, 0xa3, 0x21, 0xb7, 0xe7, 0x71, 0xc4, 0x23, 0x84, 0xa6, 0x9f, + 0xdb, 0xa1, 0xe7, 0x87, 0x4b, 0x5b, 0xa1, 0xcc, 0x3d, 0xae, 0x83, 0x17, 0x79, 0x91, 0x9a, 0xaf, + 0xc3, 0xcb, 0x88, 0x69, 0xdb, 0xfa, 0xfa, 0x24, 0x0a, 0xa7, 0xbe, 0xa7, 0xb5, 0xaa, 0x72, 0x53, + 0x8a, 0xe5, 0x45, 0x91, 0x37, 0xa3, 0x6d, 0xa9, 0x1d, 0x2d, 0xa6, 0x6d, 0xee, 0x07, 0x94, 0x71, + 0x12, 0xcc, 0xb5, 0xc1, 0x03, 0x77, 0xee, 0xb0, 0x68, 0xca, 0x7f, 0x22, 0x31, 0x75, 0x5c, 0xca, + 0x89, 0x3f, 0x63, 0x6a, 0xaa, 0xf9, 0x4f, 0x0e, 0xee, 0x75, 0xc5, 0xe2, 0xdb, 0x51, 0x18, 0xd2, + 0x09, 0xc7, 0xf4, 0xc7, 0x05, 0x65, 0x1c, 0x3d, 0x81, 0x42, 0x40, 0x39, 0xa9, 0xe5, 0x1a, 0x46, + 0xab, 0xda, 0x79, 0xcf, 0xbe, 0x9a, 0xa9, 0x2d, 0xdd, 0xbe, 0xa1, 0x9c, 0xf4, 0xca, 0x69, 0x62, + 0x49, 0x73, 0x2c, 0x47, 0xb4, 0x03, 0x25, 0xbd, 0x4a, 0x2d, 0xdf, 0xc8, 0xb7, 0xaa, 0x9d, 0xc6, + 0x75, 0xfe, 0x43, 0xa1, 0xf7, 0x95, 0x5d, 0xaf, 0x9a, 0x26, 0x56, 0xe6, 0x84, 0x33, 0x01, 0x7d, + 0x05, 0x05, 0x41, 0x41, 0xad, 0x20, 0xb3, 0x78, 0x78, 0x5d, 0x94, 0x67, 0x11, 0xe3, 0xbb, 0xe1, + 0x34, 0x52, 0x49, 0x08, 0x6b, 0x2c, 0x47, 0xf4, 0xb3, 0x01, 0x75, 0x97, 0x70, 0x32, 0x9f, 0x91, + 0x90, 0x5e, 0xd9, 0x7e, 0xad, 0x28, 0x13, 0xfb, 0xf8, 0xba, 0x90, 0xfd, 0xcc, 0xeb, 0x40, 0x3b, + 0x65, 0x49, 0x6e, 0xa5, 0x89, 0x75, 0x4b, 0x4c, 0x5c, 0x73, 0x6f, 0xf0, 0xdc, 0x2b, 0x94, 0x0d, + 0x33, 0x87, 0xcb, 0xbe, 0x4b, 0x43, 0xee, 0xf3, 0xd3, 0xe6, 0x6f, 0x39, 0x40, 0xab, 0xb4, 0x1f, + 0x70, 0xc2, 0x17, 0x0c, 0x1d, 0x01, 0x30, 0x29, 0x6d, 0x47, 0x2e, 0xad, 0x19, 0x0d, 0xa3, 0xb5, + 0xd9, 0xf9, 0xec, 0x46, 0xee, 0x2f, 0xf9, 0xda, 0x07, 0xe7, 0x8e, 0xbd, 0xbb, 0x69, 0x62, 0x55, + 0x55, 0x20, 0x67, 0x12, 0xb9, 0x14, 0xaf, 0x44, 0x45, 0x1f, 0x40, 0x29, 0xa0, 0x8c, 0x11, 0x8f, + 0xca, 0xc3, 0xad, 0x28, 0xea, 0x35, 0x84, 0x33, 0x01, 0x59, 0x50, 0xa4, 0x71, 0x1c, 0xc5, 0xb5, + 0xbc, 0x34, 0xaa, 0xa4, 0x89, 0xa5, 0x00, 0xac, 0x3e, 0xcd, 0x1f, 0x00, 0x2e, 0x96, 0x44, 0xf7, + 0xe0, 0xee, 0xf6, 0x68, 0x38, 0x1c, 0x6c, 0x8f, 0x9d, 0xc3, 0xe1, 0xf3, 0xe1, 0xe8, 0xc5, 0xd0, + 0xbc, 0x83, 0x36, 0x01, 0x32, 0x70, 0xf4, 0xdc, 0x34, 0x50, 0x1d, 0xde, 0xce, 0x74, 0x3c, 0xd8, + 0x1b, 0x6c, 0x8f, 0x07, 0x7d, 0x67, 0x34, 0x7e, 0x36, 0xc0, 0x66, 0x0e, 0xbd, 0x0b, 0xef, 0x5c, + 0x99, 0xeb, 0x1f, 0x7e, 0xeb, 0xec, 0xf6, 0xcd, 0x7c, 0xf3, 0x77, 0x03, 0xee, 0x5f, 0xbe, 0xa5, + 0x6c, 0x1e, 0x85, 0x8c, 0xa2, 0x31, 0xac, 0x4b, 0x52, 0x1c, 0x55, 0x1d, 0x92, 0xb2, 0x6a, 0xc7, + 0xba, 0x8d, 0xb2, 0xa9, 0xef, 0xf5, 0xcc, 0x34, 0xb1, 0x2e, 0x39, 0x62, 0x55, 0x97, 0x6a, 0x1a, + 0xed, 0xc1, 0x9a, 0x22, 0x4c, 0x5f, 0xff, 0x47, 0x6f, 0x76, 0x04, 0x3d, 0x48, 0x13, 0x4b, 0x7b, + 0x62, 0xfd, 0x6d, 0xde, 0xbf, 0x38, 0x68, 0xb1, 0x8e, 0x2a, 0xaf, 0xe6, 0xdf, 0x06, 0x54, 0x57, + 0xe0, 0xd5, 0x8a, 0x51, 0x5b, 0x68, 0xdc, 0xb8, 0xe4, 0xed, 0x15, 0xb3, 0x03, 0xa5, 0x59, 0xe4, + 0x79, 0x34, 0xce, 0x72, 0xbf, 0x39, 0xd0, 0x7e, 0xe4, 0x79, 0x7e, 0xe8, 0xa9, 0x40, 0xda, 0x09, + 0x67, 0x82, 0x08, 0xa4, 0xa8, 0x61, 0xf2, 0x06, 0xdc, 0x10, 0x28, 0xdb, 0xd5, 0x3c, 0x8a, 0xb9, + 0x0a, 0xa4, 0x9d, 0x70, 0x26, 0x34, 0x7f, 0x35, 0x60, 0x7d, 0x35, 0x71, 0xd4, 0x82, 0xf2, 0x94, + 0x12, 0xbe, 0x88, 0xa9, 0xd8, 0x6c, 0xbe, 0x55, 0xe9, 0xad, 0xa7, 0x89, 0x75, 0x8e, 0xe1, 0x73, + 0x09, 0xd9, 0x00, 0x74, 0xc9, 0x69, 0xc8, 0xfc, 0x28, 0x14, 0xfb, 0x11, 0xb6, 0x9b, 0x69, 0x62, + 0xad, 0xa0, 0x78, 0x45, 0x46, 0x0f, 0xa1, 0xc0, 0x89, 0xa7, 0x9a, 0x4e, 0x45, 0x35, 0x04, 0xa1, + 0x63, 0x39, 0x8a, 0x1b, 0x4d, 0x66, 0x3e, 0x61, 0xb2, 0x9b, 0xe8, 0x1b, 0x2d, 0x01, 0xac, 0x3e, + 0xcd, 0x7f, 0x73, 0x3a, 0x53, 0xcd, 0x0c, 0xda, 0x81, 0xe2, 0x8c, 0x9e, 0xd0, 0x99, 0xae, 0xc4, + 0x47, 0xaf, 0xa3, 0xd2, 0xde, 0x17, 0xd6, 0x2a, 0xb2, 0x74, 0xc4, 0xea, 0x83, 0x1e, 0x40, 0xde, + 0xf5, 0x63, 0x5d, 0x6f, 0xa5, 0x34, 0xb1, 0x84, 0x8a, 0xc5, 0x20, 0x72, 0x9e, 0xfa, 0x33, 0xaa, + 0xcb, 0x4c, 0xe6, 0x2c, 0x74, 0x2c, 0x47, 0xf4, 0x21, 0x94, 0x03, 0xb2, 0x74, 0x98, 0xff, 0x8a, + 0xca, 0xb4, 0x37, 0x14, 0x57, 0x19, 0x86, 0x4b, 0x01, 0x59, 0x1e, 0xf8, 0xaf, 0x28, 0xfa, 0x14, + 0xaa, 0x02, 0x3c, 0x22, 0x93, 0xe3, 0xc5, 0x5c, 0x74, 0x37, 0x61, 0x2b, 0xfb, 0xc0, 0x0a, 0x8c, + 0x21, 0x20, 0xcb, 0x9e, 0x92, 0xd1, 0xfb, 0x20, 0x9c, 0x1d, 0xd1, 0x07, 0xd6, 0xa4, 0xb5, 0xea, + 0x03, 0x0a, 0xc2, 0x6b, 0x01, 0x59, 0x76, 0x3d, 0x2a, 0x0e, 0x6b, 0x12, 0x05, 0xf3, 0x98, 0x32, + 0x56, 0x2b, 0x35, 0x8c, 0x56, 0x59, 0x25, 0x90, 0x61, 0xf8, 0x5c, 0x6a, 0x7e, 0x0d, 0x45, 0xb9, + 0x7d, 0x54, 0x86, 0xc2, 0xee, 0xf0, 0xe9, 0xc8, 0xbc, 0x83, 0x2a, 0x50, 0xec, 0x0f, 0x7a, 0x87, + 0x3b, 0xa6, 0x21, 0xc0, 0x17, 0x5d, 0x3c, 0x34, 0x73, 0x02, 0x1c, 0x60, 0x3c, 0xc2, 0x66, 0x5e, + 0x88, 0x4f, 0xbb, 0xe3, 0xee, 0xbe, 0x59, 0x68, 0xfe, 0x92, 0x87, 0xca, 0xf9, 0x83, 0x22, 0x7a, + 0xd4, 0x09, 0x8d, 0xc5, 0xa1, 0x4a, 0xea, 0x75, 0x8f, 0xd2, 0x10, 0xce, 0x04, 0xf4, 0x18, 0xd6, + 0x5d, 0x9f, 0xcd, 0x67, 0xe4, 0xd4, 0x09, 0x49, 0x90, 0xf5, 0x33, 0x59, 0xdc, 0xab, 0x38, 0xae, + 0x6a, 0x6d, 0x48, 0x02, 0x2a, 0xce, 0x82, 0x13, 0x4f, 0xdf, 0x11, 0x79, 0x16, 0x9c, 0x78, 0x58, + 0x0c, 0xe8, 0x4b, 0xd8, 0xf4, 0x43, 0xc6, 0x49, 0x38, 0xa1, 0x8e, 0x17, 0x47, 0x8b, 0xb9, 0xe4, + 0xb1, 0xd2, 0x43, 0x69, 0x62, 0xfd, 0x6f, 0x06, 0x6f, 0x64, 0xfa, 0x8e, 0x50, 0x51, 0x17, 0x4a, + 0x8b, 0xb9, 0x4b, 0x38, 0x75, 0x25, 0x9b, 0xd5, 0x4e, 0xdd, 0x56, 0xaf, 0xb2, 0x9d, 0xbd, 0xca, + 0xf6, 0x38, 0x7b, 0x95, 0xd5, 0x6e, 0xb4, 0x39, 0xce, 0x04, 0xf4, 0x09, 0x00, 0x3b, 0x65, 0x9c, + 0x06, 0xce, 0xc2, 0x77, 0x25, 0xd9, 0xfa, 0xb6, 0x5f, 0xa0, 0xb8, 0xa2, 0xe4, 0x43, 0xdf, 0x45, + 0xdf, 0xc1, 0x86, 0xea, 0x60, 0x59, 0xe3, 0x28, 0xbf, 0x61, 0xe3, 0x78, 0x2b, 0x4d, 0xac, 0xcb, + 0xae, 0x58, 0xf5, 0xc2, 0x8b, 0xc7, 0xaa, 0x60, 0x16, 0x2f, 0x36, 0x28, 0x39, 0xec, 0x7d, 0xf1, + 0xc7, 0xd9, 0x96, 0xf1, 0xe7, 0xd9, 0x96, 0xf1, 0xd7, 0xd9, 0x96, 0xf1, 0xfd, 0x47, 0x9e, 0xcf, + 0x5f, 0x2e, 0x8e, 0xec, 0x49, 0x14, 0xb4, 0xe5, 0x62, 0x6d, 0x19, 0xa1, 0xcd, 0xdc, 0xe3, 0xf6, + 0x49, 0x47, 0xfd, 0x89, 0x3c, 0x51, 0x3b, 0x5f, 0x93, 0x9f, 0xc7, 0xff, 0x05, 0x00, 0x00, 0xff, + 0xff, 0xb4, 0x95, 0x5a, 0x2d, 0xfa, 0x08, 0x00, 0x00, } func (m *AgentConnectRequest) Marshal() (dAtA []byte, err error) { @@ -1141,6 +1150,18 @@ func (m *AgentMeta) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.AgentDetails != nil { + { + size, err := m.AgentDetails.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAgent(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } if len(m.SystemUid) > 0 { i -= len(m.SystemUid) copy(dAtA[i:], m.SystemUid) @@ -1416,6 +1437,10 @@ func (m *AgentMeta) Size() (n int) { if l > 0 { n += 1 + l + sovAgent(uint64(l)) } + if m.AgentDetails != nil { + l = m.AgentDetails.Size() + n += 1 + l + sovAgent(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -2701,6 +2726,42 @@ func (m *AgentMeta) Unmarshal(dAtA []byte) error { } m.SystemUid = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AgentDetails", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAgent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAgent + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAgent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AgentDetails == nil { + m.AgentDetails = &AgentDetails{} + } + if err := m.AgentDetails.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAgent(dAtA[iNdEx:]) diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/agent.proto b/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/agent.proto index 92894732f..7aa32e2e0 100644 --- a/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/agent.proto +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/agent.proto @@ -78,4 +78,5 @@ message AgentMeta { string instance_group = 5 [(gogoproto.jsontag) = "instance_group"]; google.protobuf.Timestamp updated = 6 [(gogoproto.jsontag) = "updated"]; string system_uid = 7 [(gogoproto.jsontag) = "system_uid"]; + AgentDetails agent_details = 8 [(gogoproto.jsontag) = "agent_details"]; } diff --git a/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/metrics.svc.proto b/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/metrics.svc.proto index 2b84942f1..81959dda8 100644 --- a/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/metrics.svc.proto +++ b/test/performance/vendor/github.com/nginx/agent/sdk/v2/proto/metrics.svc.proto @@ -7,10 +7,6 @@ import "events/event.proto"; import "metrics.proto"; // MetricsService is responsible for ingesting high volume metrics and events -// Note: -// The naming of MetricsService is unfortunate, it is extended to StreamEvents -// to keep backward and forward compatability with NGINX Management Suite products -// This will be refactored when a major revision change for NGINX Agent is introduced service MetricsService { // A client-to-server streaming RPC to deliver high volume metrics reports. rpc Stream(stream MetricsReport) returns (google.protobuf.Empty) {} diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/config.go b/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/config.go index 1d89affea..2babeb75f 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/config.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/config.go @@ -10,6 +10,7 @@ import ( "strings" "time" + agent_config "github.com/nginx/agent/sdk/v2/agent/config" advanced_metrics "github.com/nginx/agent/v2/src/extensions/advanced-metrics/pkg/advanced-metrics" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -40,7 +41,7 @@ const ( ) var ( - Viper = viper.NewWithOptions(viper.KeyDelimiter(KeyDelimiter)) + Viper = viper.NewWithOptions(viper.KeyDelimiter(agent_config.KeyDelimiter)) ) func SetVersion(version, commit string) { @@ -177,7 +178,7 @@ func GetConfig(clientId string) (*Config, error) { Nginx: getNginx(), Dataplane: getDataplane(), AgentMetrics: getMetrics(), - Features: Viper.GetStringSlice(FeaturesKey), + Features: Viper.GetStringSlice(agent_config.FeaturesKey), Tags: Viper.GetStringSlice(TagsKey), Updated: filePathUTime(Viper.GetString(DynamicConfigPathKey)), AllowedDirectoriesMap: map[string]struct{}{}, @@ -231,8 +232,8 @@ func UpdateAgentConfig(systemId string, updateTags []string, updateFeatures []st sort.Strings(config.Features) synchronizedFeatures := reflect.DeepEqual(updateFeatures, config.Features) - Viper.Set(FeaturesKey, updateFeatures) - config.Features = Viper.GetStringSlice(FeaturesKey) + Viper.Set(agent_config.FeaturesKey, updateFeatures) + config.Features = Viper.GetStringSlice(agent_config.FeaturesKey) // If the features are already synchronized there is no need to overwrite if synchronizedTags && synchronizedFeatures { diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go b/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go index 2fe70c56f..28f8fc4ca 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/core/config/defaults.go @@ -5,6 +5,8 @@ import ( "time" "github.com/google/uuid" + + agent_config "github.com/nginx/agent/sdk/v2/agent/config" advanced_metrics "github.com/nginx/agent/v2/src/extensions/advanced-metrics/pkg/advanced-metrics" log "github.com/sirupsen/logrus" ) @@ -78,6 +80,7 @@ var ( PriorityTableMaxSize: 1000, }, }, + Features: agent_config.GetDefaultFeatures(), NAPMonitoring: NAPMonitoring{ ProcessorBufferSize: 50000, CollectorBufferSize: 50000, @@ -86,18 +89,6 @@ var ( ReportInterval: time.Minute, ReportCount: 400, }, - Features: []string{ - FeatureRegistration, - FeatureNginxConfig, - FeatureNginxSSLConfig, - FeatureNginxCounting, - FeatureMetrics, - FeatureMetricsThrottle, - FeatureDataPlaneStatus, - FeatureProcessWatcher, - FeatureFileWatcher, - FeatureActivityEvents, - }, } AllowedDirectoriesMap map[string]struct{} ) @@ -107,7 +98,6 @@ const ( DynamicConfigFileAbsPath = "/etc/nginx-agent/agent-dynamic.conf" ConfigFileName = "nginx-agent.conf" ConfigFileType = "yaml" - KeyDelimiter = "_" EnvPrefix = "nms" ConfigPathKey = "path" DynamicConfigPathKey = "dynamic-config-path" @@ -122,91 +112,77 @@ const ( // viper keys used in config LogKey = "log" - LogLevel = LogKey + KeyDelimiter + "level" - LogPath = LogKey + KeyDelimiter + "path" + LogLevel = LogKey + agent_config.KeyDelimiter + "level" + LogPath = LogKey + agent_config.KeyDelimiter + "path" // viper keys used in config ServerKey = "server" - ServerHost = ServerKey + KeyDelimiter + "host" - ServerGrpcport = ServerKey + KeyDelimiter + "grpcport" - ServerToken = ServerKey + KeyDelimiter + "token" - ServerMetrics = ServerKey + KeyDelimiter + "metrics" - ServerCommand = ServerKey + KeyDelimiter + "command" + ServerHost = ServerKey + agent_config.KeyDelimiter + "host" + ServerGrpcport = ServerKey + agent_config.KeyDelimiter + "grpcport" + ServerToken = ServerKey + agent_config.KeyDelimiter + "token" + ServerMetrics = ServerKey + agent_config.KeyDelimiter + "metrics" + ServerCommand = ServerKey + agent_config.KeyDelimiter + "command" // viper keys used in config TlsKey = "tls" - TlsEnable = TlsKey + KeyDelimiter + "enable" - TlsCert = TlsKey + KeyDelimiter + "cert" - TlsPrivateKey = TlsKey + KeyDelimiter + "key" - TlsCa = TlsKey + KeyDelimiter + "ca" - TlsSkipVerify = TlsKey + KeyDelimiter + "skip_verify" + TlsEnable = TlsKey + agent_config.KeyDelimiter + "enable" + TlsCert = TlsKey + agent_config.KeyDelimiter + "cert" + TlsPrivateKey = TlsKey + agent_config.KeyDelimiter + "key" + TlsCa = TlsKey + agent_config.KeyDelimiter + "ca" + TlsSkipVerify = TlsKey + agent_config.KeyDelimiter + "skip_verify" // viper keys used in config NginxKey = "nginx" - NginxExcludeLogs = NginxKey + KeyDelimiter + "exclude_logs" - NginxDebug = NginxKey + KeyDelimiter + "debug" - NginxCountingSocket = NginxKey + KeyDelimiter + "socket" - NginxClientVersion = NginxKey + KeyDelimiter + "client_version" + NginxExcludeLogs = NginxKey + agent_config.KeyDelimiter + "exclude_logs" + NginxDebug = NginxKey + agent_config.KeyDelimiter + "debug" + NginxCountingSocket = NginxKey + agent_config.KeyDelimiter + "socket" + NginxClientVersion = NginxKey + agent_config.KeyDelimiter + "client_version" // viper keys used in config DataplaneKey = "dataplane" - DataplaneEventsEnable = DataplaneKey + KeyDelimiter + "events_enable" - DataplaneSyncEnable = DataplaneKey + KeyDelimiter + "sync_enable" - DataplaneStatusPoll = DataplaneKey + KeyDelimiter + "status_poll_interval" - DataplaneStatusReportInterval = DataplaneKey + KeyDelimiter + "report_interval" + DataplaneEventsEnable = DataplaneKey + agent_config.KeyDelimiter + "events_enable" + DataplaneSyncEnable = DataplaneKey + agent_config.KeyDelimiter + "sync_enable" + DataplaneStatusPoll = DataplaneKey + agent_config.KeyDelimiter + "status_poll_interval" + DataplaneStatusReportInterval = DataplaneKey + agent_config.KeyDelimiter + "report_interval" // viper keys used in config MetricsKey = "metrics" - MetricsBulkSize = MetricsKey + KeyDelimiter + "bulk_size" - MetricsReportInterval = MetricsKey + KeyDelimiter + "report_interval" - MetricsCollectionInterval = MetricsKey + KeyDelimiter + "collection_interval" - MetricsMode = MetricsKey + KeyDelimiter + "mode" + MetricsBulkSize = MetricsKey + agent_config.KeyDelimiter + "bulk_size" + MetricsReportInterval = MetricsKey + agent_config.KeyDelimiter + "report_interval" + MetricsCollectionInterval = MetricsKey + agent_config.KeyDelimiter + "collection_interval" + MetricsMode = MetricsKey + agent_config.KeyDelimiter + "mode" // viper keys used in config AdvancedMetricsKey = "advanced_metrics" - AdvancedMetricsSocketPath = AdvancedMetricsKey + KeyDelimiter + "socket_path" - AdvancedMetricsAggregationPeriod = AdvancedMetricsKey + KeyDelimiter + "aggregation_period" - AdvancedMetricsPublishPeriod = AdvancedMetricsKey + KeyDelimiter + "publishing_period" - AdvancedMetricsTableSizesLimits = AdvancedMetricsKey + KeyDelimiter + "table_sizes_limits" - AdvancedMetricsTableSizesLimitsSTMS = AdvancedMetricsTableSizesLimits + KeyDelimiter + "staging_table_max_size" - AdvancedMetricsTableSizesLimitsSTT = AdvancedMetricsTableSizesLimits + KeyDelimiter + "staging_table_threshold" - AdvancedMetricsTableSizesLimitsPTMS = AdvancedMetricsTableSizesLimits + KeyDelimiter + "priority_table_max_size" - AdvancedMetricsTableSizesLimitsPTT = AdvancedMetricsTableSizesLimits + KeyDelimiter + "priority_table_threshold" + AdvancedMetricsSocketPath = AdvancedMetricsKey + agent_config.KeyDelimiter + "socket_path" + AdvancedMetricsAggregationPeriod = AdvancedMetricsKey + agent_config.KeyDelimiter + "aggregation_period" + AdvancedMetricsPublishPeriod = AdvancedMetricsKey + agent_config.KeyDelimiter + "publishing_period" + AdvancedMetricsTableSizesLimits = AdvancedMetricsKey + agent_config.KeyDelimiter + "table_sizes_limits" + AdvancedMetricsTableSizesLimitsSTMS = AdvancedMetricsTableSizesLimits + agent_config.KeyDelimiter + "staging_table_max_size" + AdvancedMetricsTableSizesLimitsSTT = AdvancedMetricsTableSizesLimits + agent_config.KeyDelimiter + "staging_table_threshold" + AdvancedMetricsTableSizesLimitsPTMS = AdvancedMetricsTableSizesLimits + agent_config.KeyDelimiter + "priority_table_max_size" + AdvancedMetricsTableSizesLimitsPTT = AdvancedMetricsTableSizesLimits + agent_config.KeyDelimiter + "priority_table_threshold" // viper keys used in config NginxAppProtectKey = "nginx_app_protect" - NginxAppProtectReportInterval = NginxAppProtectKey + KeyDelimiter + "report_interval" + NginxAppProtectReportInterval = NginxAppProtectKey + agent_config.KeyDelimiter + "report_interval" // viper keys used in config NAPMonitoringKey = "nap_monitoring" - NAPMonitoringCollectorBufferSize = NAPMonitoringKey + KeyDelimiter + "collector_buffer_size" - NAPMonitoringProcessorBufferSize = NAPMonitoringKey + KeyDelimiter + "processor_buffer_size" - NAPMonitoringSyslogIP = NAPMonitoringKey + KeyDelimiter + "syslog_ip" - NAPMonitoringSyslogPort = NAPMonitoringKey + KeyDelimiter + "syslog_port" - NAPMonitoringReportInterval = NAPMonitoringKey + KeyDelimiter + "report_interval" - NAPMonitoringReportCount = NAPMonitoringKey + KeyDelimiter + "report_count" - - // viper keys used in config - FeaturesKey = "features" - - FeatureRegistration = FeaturesKey + KeyDelimiter + "registration" - FeatureNginxConfig = FeaturesKey + KeyDelimiter + "nginx-config" - FeatureNginxSSLConfig = FeaturesKey + KeyDelimiter + "nginx-ssl-config" - FeatureNginxCounting = FeaturesKey + KeyDelimiter + "nginx-counting" - FeatureMetrics = FeaturesKey + KeyDelimiter + "metrics" - FeatureMetricsThrottle = FeaturesKey + KeyDelimiter + "metrics-throttle" - FeatureDataPlaneStatus = FeaturesKey + KeyDelimiter + "dataplane-status" - FeatureProcessWatcher = FeaturesKey + KeyDelimiter + "process-watcher" - FeatureFileWatcher = FeaturesKey + KeyDelimiter + "file-watcher" - FeatureActivityEvents = FeaturesKey + KeyDelimiter + "activity-events" + NAPMonitoringCollectorBufferSize = NAPMonitoringKey + agent_config.KeyDelimiter + "collector_buffer_size" + NAPMonitoringProcessorBufferSize = NAPMonitoringKey + agent_config.KeyDelimiter + "processor_buffer_size" + NAPMonitoringSyslogIP = NAPMonitoringKey + agent_config.KeyDelimiter + "syslog_ip" + NAPMonitoringSyslogPort = NAPMonitoringKey + agent_config.KeyDelimiter + "syslog_port" + NAPMonitoringReportInterval = NAPMonitoringKey + agent_config.KeyDelimiter + "report_interval" + NAPMonitoringReportCount = NAPMonitoringKey + agent_config.KeyDelimiter + "report_count" // DEPRECATED KEYS NginxBinPathKey = "nginx_bin_path" @@ -268,9 +244,9 @@ var ( Usage: "A comma-separated list of tags to add to the current instance or machine, to be used for inventory purposes.", }, &StringSliceFlag{ - Name: FeaturesKey, + Name: agent_config.FeaturesKey, Usage: "A comma-separated list of features enabled for the agent.", - DefaultValue: Defaults.Features, + DefaultValue: agent_config.GetDefaultFeatures(), }, // NGINX Config &StringFlag{ 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 a04d32037..f932e4b22 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 @@ -20,6 +20,7 @@ type Config struct { AgentMetrics AgentMetrics `mapstructure:"metrics" yaml:"-"` Tags []string `mapstructure:"tags" yaml:"tags,omitempty"` Features []string `mapstructure:"features" yaml:"features,omitempty"` + Extensions []string `mapstructure:"extensions" yaml:"extensions,omitempty"` Updated time.Time `yaml:"-"` // update time of the config file AllowedDirectoriesMap map[string]struct{} `yaml:"-"` DisplayName string `mapstructure:"display_name" yaml:"display_name,omitempty"` 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 6ae1c1eb0..9c251993c 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 @@ -19,6 +19,11 @@ const ( NginxWorkerProcCreated = "nginx.worker.created" NginxWorkerProcKilled = "nginx.worker.killed" NginxDetailProcUpdate = "nginx.proc.update" + NginxConfigValidationPending = "nginx.config.validation.pending" + NginxConfigValidationFailed = "nginx.config.validation.failed" + NginxConfigValidationSucceeded = "nginx.config.validation.succeeded" + NginxConfigApplyFailed = "nginx.config.apply.failed" + NginxConfigApplySucceeded = "nginx.config.apply.succeeded" CommPrefix = "comms." CommStatus = CommPrefix + "status" CommMetrics = CommPrefix + "metrics" diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/collector/nap.go b/test/performance/vendor/github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/collector/nap.go index 1888dda02..c11a2e3ab 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/collector/nap.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/collector/nap.go @@ -35,24 +35,21 @@ type syslogServer struct { } // NewNAPCollector gives you a NAP collector for the syslog server. -func NewNAPCollector(cfg *NAPConfig) (*NAPCollector, error) { - var ( - c NAPCollector - err error - ) +func NewNAPCollector(cfg *NAPConfig) (napCollector *NAPCollector, err error) { + napCollector = &NAPCollector{} - c.logger = logrus.StandardLogger().WithFields(componentLogFields) + napCollector.logger = logrus.StandardLogger().WithFields(componentLogFields) if cfg.Logger != nil { - c.logger = cfg.Logger.WithFields(componentLogFields) + napCollector.logger = cfg.Logger.WithFields(componentLogFields) } - c.logger.Infof("Getting %s Collector", monitoring.NAP) + napCollector.logger.Infof("Getting %s Collector", monitoring.NAP) - c.syslog, err = newSyslogServer(c.logger, cfg.SyslogIP, cfg.SyslogPort) + napCollector.syslog, err = newSyslogServer(napCollector.logger, cfg.SyslogIP, cfg.SyslogPort) if err != nil { return nil, err } - return &c, nil + return napCollector, nil } func newSyslogServer(logger *logrus.Entry, ip string, port int) (*syslogServer, error) { diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/manager/manager.go b/test/performance/vendor/github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/manager/manager.go index bda73e1ef..8d5f45b54 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/manager/manager.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/manager/manager.go @@ -2,16 +2,17 @@ package manager import ( "context" - "github.com/nginx/agent/v2/src/core/metrics" "runtime" "sync" + log "github.com/sirupsen/logrus" + models "github.com/nginx/agent/sdk/v2/proto/events" "github.com/nginx/agent/v2/src/core/config" + "github.com/nginx/agent/v2/src/core/metrics" "github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring" "github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/collector" "github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/processor" - log "github.com/sirupsen/logrus" ) const ( diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/processor/nap.go b/test/performance/vendor/github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/processor/nap.go index 1663c4376..b64287f40 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/processor/nap.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/processor/nap.go @@ -25,6 +25,7 @@ const ( var ( logFormatKeys = []string{ + // TODO: Remove `date_time` from syslog format as it is unused (NMS-38119) "date_time", "blocking_exception_reason", "dest_port", @@ -65,7 +66,7 @@ var ( ) const ( - // TODO: Identify the usage of the following new keys + // TODO: Identify the usage of the following new keys (NMS-38311) blockingExceptionReason = "blocking_exception_reason" protocol = "protocol" requestStatus = "request_status" @@ -77,22 +78,6 @@ const ( clientApplication = "client_application" clientApplicationVersion = "client_application_version" transportProtocol = "transport_protocol" - - // Using default values instead of overriden keys per older CAS policy - httpRequestMethod = "method" - httpResponseCode = "response_code" - sigCVEs = "sig_cves" - sigIds = "sig_ids" - sigNames = "sig_names" - httpRemotePort = "src_port" - httpURI = "uri" - httpHostname = "vs_name" - requestOutcome = "outcome" - requestOutcomeReason = "outcome_reason" - httpRemoteAddr = "ip_client" - httpServerPort = "dest_port" - isTruncated = "is_truncated" - // Older CAS Naming (this needs to be removed) // httpRequestMethod = "http_request_method" // httpResponseCode = "http_response_code" @@ -110,6 +95,21 @@ const ( // httpServerPort = "http_server_port" // isTruncated = "is_truncated_bool" + // Using default values instead of overriden keys per older CAS policy + httpRequestMethod = "method" + httpResponseCode = "response_code" + sigCVEs = "sig_cves" + sigIds = "sig_ids" + sigNames = "sig_names" + httpRemotePort = "src_port" + httpURI = "uri" + httpHostname = "vs_name" + requestOutcome = "outcome" + requestOutcomeReason = "outcome_reason" + httpRemoteAddr = "ip_client" + httpServerPort = "dest_port" + isTruncated = "is_truncated" + // Existing parsed keys from the log dateTime = "date_time" policyName = "policy_name" @@ -301,8 +301,7 @@ func (f *NAPConfig) getSecurityViolation(logger *logrus.Entry) *models.SecurityV EnforcedBotAnomalies: f.EnforcedBotAnomalies, ViolationContexts: f.getViolationContext(), ViolationsData: f.getViolations(logger), - // The following items needs to be fixed before release - // TODO: https://nginxsoftware.atlassian.net/browse/NMS-38119 + // TODO: The following items needs to be fixed before release (NMS-38119) DateTime: f.DateTime, // remove, metadata has it Outcome: f.RequestOutcome, //rename the proto OutcomeReason: f.RequestOutcomeReason, //rename the proto @@ -316,8 +315,6 @@ func (f *NAPConfig) getSecurityViolation(logger *logrus.Entry) *models.SecurityV } func (f *NAPConfig) getMetadata() (*models.Metadata, error) { - // Set date time as current time with format YYYY-MM-DD HH:MM:SS.SSS - // This is a temporary solution - https://nginxsoftware.atlassian.net/browse/IND-10651 f.DateTime = time.Now().UTC().Format(napDateTimeLayout) t, err := parseNAPDateTime(f.DateTime) @@ -325,9 +322,7 @@ func (f *NAPConfig) getMetadata() (*models.Metadata, error) { return nil, err } - // set the correlation ID correctly - // TODO: https://nginxsoftware.atlassian.net/browse/NMS-37563 - return NewMetadata(t, "123") + return NewMetadata(t, f.SupportID) } func (f *NAPConfig) getViolationContext() string { @@ -474,11 +469,10 @@ func parseNAPDateTime(raw string) (*types.Timestamp, error) { return types.TimestampProto(t) } -// Assumptions while parsing the NAP Syslog data: +// TODO: Assumptions while parsing the NAP Syslog data (NMS-38118) // 1. list values do not contain `commas`, rather have `::` as delimiter // 2. no json values // 3. no other comma exists in the response other than the delimiter comma -// TODO: https://nginxsoftware.atlassian.net/browse/NMS-38118 func parseNAP(logEntry string, logger *logrus.Entry) (*NAPConfig, error) { var waf NAPConfig diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/processor/processor.go b/test/performance/vendor/github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/processor/processor.go index 0906b8990..6c96a042c 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/processor/processor.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/processor/processor.go @@ -4,13 +4,13 @@ import ( "context" "errors" "fmt" - "github.com/nginx/agent/v2/src/core/metrics" "regexp" "sync" "github.com/sirupsen/logrus" pb "github.com/nginx/agent/sdk/v2/proto/events" + "github.com/nginx/agent/v2/src/core/metrics" "github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring" ) @@ -62,6 +62,10 @@ func GetClient(cfg *Config) (*Client, error) { } c.hostPattern = hostPattern + if cfg.CommonDims == nil { + c.logger.Warnf("common dimensions are not passed to NAP Monitoring processor") + cfg.CommonDims = &metrics.CommonDim{} + } c.commonDims = cfg.CommonDims return &c, nil @@ -93,6 +97,18 @@ func (c *Client) processorWorker(ctx context.Context, wg *sync.WaitGroup, id int break } + if event.GetSecurityViolationEvent() == nil { + c.logger.Errorf("event expected as SecurityViolationEvent from nap monitor processing") + break + } + + event.GetSecurityViolationEvent().SystemID = c.commonDims.SystemId + event.GetSecurityViolationEvent().Hostname = c.commonDims.Hostname + event.GetSecurityViolationEvent().InstanceTags = c.commonDims.InstanceTags + event.GetSecurityViolationEvent().InstanceGroup = c.commonDims.InstanceGroup + event.GetSecurityViolationEvent().DisplayName = c.commonDims.DisplayName + event.GetSecurityViolationEvent().NginxID = c.commonDims.NginxId + c.logger.Debugf("%d: Generated Event: %s", id, event) processed <- event diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/comms.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/comms.go index 15699f288..b0e112079 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/comms.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/comms.go @@ -141,7 +141,6 @@ func (r *Comms) reportLoop() { sb.WriteString(", ") } sb.WriteString(report.Events[l-1].GetSecurityViolationEvent().SupportID) - // TODO: In addition to the below, make sure we don't lose data https://nginxsoftware.atlassian.net/browse/NMS-38169 log.Errorf("Failed to send EventReport with error: %v, supportID list: %s", err, sb.String()) } else { log.Tracef("EventReport sent, %v", report) 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 bd5dd3ba4..8a8eda177 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 @@ -15,22 +15,23 @@ 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 + 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 } const ( @@ -87,11 +88,67 @@ func (dps *DataPlaneStatus) Process(msg *core.Message) { case msg.Exact(core.NginxAppProtectDetailsGenerated): // If a NAP report was generated sync it dps.syncNAPDetails(msg) + + case msg.Exact(core.NginxConfigValidationPending): + log.Tracef("DataplaneStatus: %T message from topic %s received", msg.Data(), msg.Topic()) + switch data := msg.Data().(type) { + case *proto.AgentActivityStatus: + dps.updateAgentActivityStatuses(data) + default: + log.Errorf("Expected the type %T but got %T", &proto.AgentActivityStatus{}, data) + } + case msg.Exact(core.NginxConfigApplyFailed) || msg.Exact(core.NginxConfigApplySucceeded): + 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.sendDataplaneStatus(dps.messagePipeline, false) + dps.removeAgentActivityStatus(data) + default: + log.Errorf("Expected the type %T but got %T", &proto.AgentActivityStatus{}, data) + } } } func (dps *DataPlaneStatus) Subscriptions() []string { - return []string{core.AgentConfigChanged, core.NginxAppProtectDetailsGenerated} + return []string{ + core.AgentConfigChanged, + core.NginxAppProtectDetailsGenerated, + core.NginxConfigValidationPending, + core.NginxConfigApplyFailed, + core.NginxConfigApplySucceeded, + } +} + +func (dps *DataPlaneStatus) updateAgentActivityStatuses(newAgentActivityStatus *proto.AgentActivityStatus) { + log.Tracef("DataplaneStatus: Adding %v to agentActivityStatuses", 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) + } + } + } } func (dps *DataPlaneStatus) sendDataplaneStatus(pipeline core.MessagePipeInterface, forceDetails bool) { @@ -133,6 +190,7 @@ func (dps *DataPlaneStatus) dataplaneStatus(forceDetails bool) *proto.DataplaneS Details: dps.detailsForProcess(processes, forceDetails), Healths: dps.healthForProcess(processes), DataplaneSoftwareDetails: dps.dataplaneSoftwareDetails(), + AgentActivityStatus: dps.agentActivityStatuses, } } diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/extensions.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/extensions.go index cf7b34260..542df28ac 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/extensions.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/extensions.go @@ -1,9 +1,10 @@ package plugins import ( + log "github.com/sirupsen/logrus" + "github.com/nginx/agent/v2/src/core" "github.com/nginx/agent/v2/src/core/config" - log "github.com/sirupsen/logrus" ) const ( diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/nap_monitoring.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/nap_monitoring.go index 99e120cb1..e1b14a1c9 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/nap_monitoring.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/nap_monitoring.go @@ -2,7 +2,6 @@ package plugins import ( "context" - "github.com/nginx/agent/v2/src/core/metrics" "time" log "github.com/sirupsen/logrus" @@ -10,6 +9,7 @@ import ( models "github.com/nginx/agent/sdk/v2/proto/events" "github.com/nginx/agent/v2/src/core" "github.com/nginx/agent/v2/src/core/config" + "github.com/nginx/agent/v2/src/core/metrics" "github.com/nginx/agent/v2/src/extensions/nginx-app-protect/monitoring/manager" ) @@ -73,12 +73,8 @@ func (n *NAPMonitoring) Init(pipeline core.MessagePipeInterface) { go n.run() } -// TODO: https://nginxsoftware.atlassian.net/browse/NMS-38140 -// - Identify if we need to process any interactions with NGINX func (n *NAPMonitoring) Process(msg *core.Message) {} -// TODO: https://nginxsoftware.atlassian.net/browse/NMS-38140 -// - Subscribe for Agent config updates func (n *NAPMonitoring) Subscriptions() []string { return []string{} } 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 2dabec01f..e22d871ce 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 @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "time" "github.com/gogo/protobuf/types" "github.com/google/uuid" @@ -11,7 +12,9 @@ import ( "github.com/nginx/agent/sdk/v2" "github.com/nginx/agent/sdk/v2/client" + "github.com/nginx/agent/sdk/v2/grpc" + agent_config "github.com/nginx/agent/sdk/v2/agent/config" "github.com/nginx/agent/sdk/v2/proto" "github.com/nginx/agent/v2/src/core" "github.com/nginx/agent/v2/src/core/config" @@ -21,16 +24,21 @@ const ( appProtectMetadataFilePath = "/etc/nms/app_protect_metadata.json" ) +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 + 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 } type ConfigRollbackResponse struct { @@ -47,6 +55,15 @@ type NginxReloadResponse struct { nginxDetails *proto.NginxDetails } +type NginxConfigValidationResponse struct { + err error + correlationId string + nginxDetails *proto.NginxDetails + config *proto.NginxConfig + configApply *sdk.ConfigApply + elapsedTime time.Duration +} + func NewNginx(cmdr client.Commander, nginxBinary core.NginxBinary, env core.Environment, loadedConfig *config.Config) *Nginx { var isNAPEnabled bool if loadedConfig.NginxAppProtect != (config.NginxAppProtect{}) { @@ -55,7 +72,16 @@ func NewNginx(cmdr client.Commander, nginxBinary core.NginxBinary, env core.Envi isConfUploadEnabled := isConfUploadEnabled(loadedConfig) - return &Nginx{nginxBinary: nginxBinary, processes: env.Processes(), env: env, cmdr: cmdr, config: loadedConfig, isNAPEnabled: isNAPEnabled, isConfUploadEnabled: isConfUploadEnabled} + return &Nginx{ + nginxBinary: nginxBinary, + processes: env.Processes(), + env: env, + cmdr: cmdr, + config: loadedConfig, + isNAPEnabled: isNAPEnabled, + isConfUploadEnabled: isConfUploadEnabled, + configApplyStatusChannel: make(chan *proto.Command_NginxConfigResponse, 1), + } } // Init initializes the plugin @@ -95,6 +121,29 @@ func (n *Nginx) Process(message *core.Message) { case core.AgentConfigChanged: // If the agent config on disk changed update this with relevant config info n.syncAgentConfigChange() + case core.NginxConfigValidationSucceeded: + switch response := message.Data().(type) { + case *NginxConfigValidationResponse: + status := n.completeConfigApply(response) + if response.elapsedTime < validationTimeout { + n.configApplyStatusChannel <- status + } + } + case core.NginxConfigValidationFailed: + switch response := message.Data().(type) { + case *NginxConfigValidationResponse: + n.rollbackConfigApply(response) + status := &proto.Command_NginxConfigResponse{ + NginxConfigResponse: &proto.NginxConfigResponse{ + Status: newErrStatus(fmt.Sprintf("Config apply failed (write): " + response.err.Error())).CmdStatus, + Action: proto.NginxConfigAction_APPLY, + ConfigData: response.config.ConfigData, + }, + } + if response.elapsedTime < validationTimeout { + n.configApplyStatusChannel <- status + } + } case core.EnableExtension: switch data := message.Data().(type) { case string: @@ -113,6 +162,9 @@ func (n *Nginx) Subscriptions() []string { core.DataplaneChanged, core.AgentConfigChanged, core.EnableExtension, + core.NginxConfigValidationPending, + core.NginxConfigValidationSucceeded, + core.NginxConfigValidationFailed, } } @@ -203,20 +255,22 @@ func (n *Nginx) processCmd(cmd *proto.Command) { } } -// The applyConfig does the following: -// - Download config -// - Stop file watcher -// - Write the config -// - Valid config -// - Upload the config -// - Start file watcher -// - Reload nginx 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 applied successfully").CmdStatus, + Status: newOKStatus("config apply request successfully processed").CmdStatus, Action: proto.NginxConfigAction_APPLY, ConfigData: cfg.NginxConfig.ConfigData, }, @@ -263,36 +317,77 @@ 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) } - err = n.nginxBinary.ValidateConfig(nginx.NginxId, nginx.ProcessPath, nginx.ConfPath, config, configApply) + go n.validateConfig(nginx, cmd.Meta.MessageId, 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 + // will be removed. + select { + 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) + return status + } +} + +// This function will run a nginx config validation in a separate go routine. If the validation takes less than 15 seconds then the result is returned straight away, +// otherwise nil is returned and the validation continues on in the background until it is complete. The result is always added to the message pipeline for other plugins +// to use. +func (n *Nginx) validateConfig(nginx *proto.NginxDetails, correlationId string, config *proto.NginxConfig, configApply *sdk.ConfigApply) { + start := time.Now() + + err := n.nginxBinary.ValidateConfig(nginx.NginxId, nginx.ProcessPath, nginx.ConfPath, config, configApply) if err == nil { _, err = n.nginxBinary.ReadConfig(nginx.GetConfPath(), config.GetConfigData().GetNginxId(), n.env.GetSystemUUID()) } - if err != nil { - if configApply != nil { - succeeded := true - if rollbackErr := configApply.Rollback(err); rollbackErr != nil { - log.Errorf("Config rollback failed: %v", rollbackErr) - succeeded = false - } + elapsedTime := time.Since(start) + log.Tracef("nginx config validation took %s to complete", elapsedTime) - configRollbackResponse := ConfigRollbackResponse{ - succeeded: succeeded, - correlationId: cmd.Meta.MessageId, - timestamp: types.TimestampNow(), - nginxDetails: nginx, - } - n.messagePipeline.Process(core.NewMessage(core.ConfigRollbackResponse, configRollbackResponse)) + if err != nil { + response := &NginxConfigValidationResponse{ + err: fmt.Errorf("error running nginx -t -c %s:\n %v", nginx.ConfPath, err), + correlationId: correlationId, + nginxDetails: nginx, + config: config, + configApply: configApply, + elapsedTime: elapsedTime, } + n.messagePipeline.Process(core.NewMessage(core.NginxConfigValidationFailed, response)) + } else { + response := &NginxConfigValidationResponse{ + err: nil, + correlationId: correlationId, + nginxDetails: nginx, + config: config, + configApply: configApply, + elapsedTime: elapsedTime, + } + n.messagePipeline.Process(core.NewMessage(core.NginxConfigValidationSucceeded, response)) + } +} - message := fmt.Sprintf("Config apply failed (write): " + err.Error()) - return n.handleErrorStatus(status, message) - } else if configApply != nil { - if err = configApply.Complete(); err != nil { - log.Errorf("Config complete failed: %v", err) +func (n *Nginx) completeConfigApply(response *NginxConfigValidationResponse) *proto.Command_NginxConfigResponse { + nginxConfigStatusMessage := "Config applied successfully" + if response.configApply != nil { + if err := response.configApply.Complete(); err != nil { + nginxConfigStatusMessage = fmt.Sprintf("Config complete failed: %v", err) + log.Errorf(nginxConfigStatusMessage) } } @@ -304,40 +399,111 @@ func (n *Nginx) applyConfig(cmd *proto.Command, cfg *proto.Command_NginxConfig) }, } - err = n.uploadConfig( + err := n.uploadConfig( &proto.ConfigDescriptor{ SystemId: n.env.GetSystemUUID(), - NginxId: config.GetConfigData().GetNginxId(), + NginxId: response.config.GetConfigData().GetNginxId(), }, - cmd.Meta.GetMessageId(), + response.correlationId, ) if err != nil { - uploadResponse.NginxConfigResponse.Status = newErrStatus("config uploaded error: " + err.Error()).CmdStatus + uploadResponse.NginxConfigResponse.Status = newErrStatus("Config uploaded error: " + err.Error()).CmdStatus + nginxConfigStatusMessage = fmt.Sprintf("Config uploaded error: %v", err) + log.Errorf(nginxConfigStatusMessage) } - uploadResponseCommand := newStatusCommand(cmd) + uploadResponseCommand := &proto.Command{Meta: grpc.NewMessageMeta(response.correlationId)} uploadResponseCommand.Data = uploadResponse n.messagePipeline.Process(core.NewMessage(core.CommResponse, uploadResponseCommand)) log.Debug("Enabling file watcher") n.messagePipeline.Process(core.NewMessage(core.FileWatcherEnabled, true)) - reloadErr := n.nginxBinary.Reload(nginx.ProcessId, nginx.ProcessPath) + reloadErr := n.nginxBinary.Reload(response.nginxDetails.ProcessId, response.nginxDetails.ProcessPath) if reloadErr != nil { - status.NginxConfigResponse.Status = newErrStatus("Config apply failed (write): " + reloadErr.Error()).CmdStatus + nginxConfigStatusMessage = fmt.Sprintf("Config apply failed (write): %v", reloadErr) + log.Errorf(nginxConfigStatusMessage) } nginxReloadEventMeta := NginxReloadResponse{ succeeded: reloadErr == nil, - correlationId: cmd.Meta.MessageId, + correlationId: response.correlationId, timestamp: types.TimestampNow(), - nginxDetails: nginx, + nginxDetails: response.nginxDetails, } + n.messagePipeline.Process(core.NewMessage(core.NginxReloadComplete, nginxReloadEventMeta)) + + agentActivityStatus := &proto.AgentActivityStatus{ + Status: &proto.AgentActivityStatus_NginxConfigStatus{ + NginxConfigStatus: &proto.NginxConfigStatus{ + CorrelationId: response.correlationId, + Status: proto.NginxConfigStatus_OK, + Message: nginxConfigStatusMessage, + }, + }, + } + + n.messagePipeline.Process(core.NewMessage(core.NginxConfigApplySucceeded, agentActivityStatus)) + + status := &proto.Command_NginxConfigResponse{ + NginxConfigResponse: &proto.NginxConfigResponse{ + Status: newOKStatus("config apply request successfully processed").CmdStatus, + Action: proto.NginxConfigAction_APPLY, + ConfigData: response.config.ConfigData, + }, + } + + if agentActivityStatus.GetNginxConfigStatus().GetStatus() == proto.NginxConfigStatus_ERROR { + status.NginxConfigResponse.Status = newErrStatus(agentActivityStatus.GetNginxConfigStatus().GetMessage()).CmdStatus + } else { + status.NginxConfigResponse.Status = newOKStatus(agentActivityStatus.GetNginxConfigStatus().GetMessage()).CmdStatus + } + log.Debug("Config Apply Complete") + return status } +func (n *Nginx) rollbackConfigApply(response *NginxConfigValidationResponse) { + nginxConfigStatusMessage := fmt.Sprintf("Config apply failed (write): %v", response.err.Error()) + log.Error(nginxConfigStatusMessage) + + if response.configApply != nil { + succeeded := true + + if rollbackErr := response.configApply.Rollback(response.err); rollbackErr != nil { + nginxConfigStatusMessage := fmt.Sprintf("Config rollback failed: %v", rollbackErr) + log.Error(nginxConfigStatusMessage) + succeeded = false + } + + configRollbackResponse := ConfigRollbackResponse{ + succeeded: succeeded, + correlationId: response.correlationId, + timestamp: types.TimestampNow(), + nginxDetails: response.nginxDetails, + } + + n.messagePipeline.Process(core.NewMessage(core.ConfigRollbackResponse, configRollbackResponse)) + + agentActivityStatus := &proto.AgentActivityStatus{ + Status: &proto.AgentActivityStatus_NginxConfigStatus{ + NginxConfigStatus: &proto.NginxConfigStatus{ + CorrelationId: response.correlationId, + Status: proto.NginxConfigStatus_ERROR, + Message: nginxConfigStatusMessage, + }, + }, + } + + n.messagePipeline.Process(core.NewMessage(core.NginxConfigApplyFailed, agentActivityStatus)) + } + + log.Debug("Enabling file watcher") + n.messagePipeline.Process(core.NewMessage(core.FileWatcherEnabled, true)) +} + func (n *Nginx) handleErrorStatus(status *proto.Command_NginxConfigResponse, message string) *proto.Command_NginxConfigResponse { status.NginxConfigResponse.Status = newErrStatus(message).CmdStatus @@ -395,7 +561,7 @@ func (n *Nginx) syncAgentConfigChange() { func isConfUploadEnabled(conf *config.Config) bool { for _, feature := range conf.Features { - if feature == config.FeatureNginxConfig { + if feature == agent_config.FeatureNginxConfig { return true } } diff --git a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go index 71edbb816..5e170bce5 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/src/plugins/registration.go @@ -131,6 +131,12 @@ func (r *OneTimeRegistration) registerAgent() { InstanceGroup: r.config.InstanceGroup, Updated: updated, SystemUid: r.env.GetSystemUUID(), + AgentDetails: &proto.AgentDetails{ + Features: r.config.Features, + Extensions: r.config.Extensions, + Tags: *r.tags, + Alias: "", + }, }, Details: details, DataplaneSoftwareDetails: r.dataplaneSoftwareDetailsSlice(), diff --git a/test/performance/vendor/github.com/nginx/agent/v2/test/utils/agent_config.go b/test/performance/vendor/github.com/nginx/agent/v2/test/utils/agent_config.go index 80fd1a5bb..58fa133dd 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/test/utils/agent_config.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/test/utils/agent_config.go @@ -9,7 +9,9 @@ import ( "github.com/spf13/viper" + agent_config "github.com/nginx/agent/sdk/v2/agent/config" "github.com/nginx/agent/v2/src/core/config" + sysutils "github.com/nginx/agent/v2/test/utils/system" log "github.com/sirupsen/logrus" ) @@ -116,7 +118,7 @@ func setupRoutine(wg *sync.WaitGroup) error { os.Clearenv() config.ROOT_COMMAND.ResetFlags() config.ROOT_COMMAND.ResetCommands() - config.Viper = viper.NewWithOptions(viper.KeyDelimiter(config.KeyDelimiter)) + config.Viper = viper.NewWithOptions(viper.KeyDelimiter(agent_config.KeyDelimiter)) config.SetDefaults() config.RegisterFlags() diff --git a/test/performance/vendor/github.com/nginx/agent/v2/test/utils/environment.go b/test/performance/vendor/github.com/nginx/agent/v2/test/utils/environment.go index 10f7d70cc..b558011ff 100644 --- a/test/performance/vendor/github.com/nginx/agent/v2/test/utils/environment.go +++ b/test/performance/vendor/github.com/nginx/agent/v2/test/utils/environment.go @@ -47,20 +47,24 @@ func NewMockEnvironment() *MockEnvironment { var _ core.Environment = NewMockEnvironment() func (m *MockEnvironment) NewHostInfo(agentVersion string, tags *[]string, configDirs string, clearCache bool) *proto.HostInfo { - m.Called(agentVersion, tags) - return &proto.HostInfo{ - Agent: agentVersion, - Boot: 0, - Hostname: "test-host", - DisplayName: "", - OsType: "", - Uuid: "", - Uname: "", - Partitons: []*proto.DiskPartition{}, - Network: &proto.Network{}, - Processor: []*proto.CpuInfo{}, - Release: &proto.ReleaseInfo{}, + args := m.Called(agentVersion, tags) + returned, ok := args.Get(0).(*proto.HostInfo) + if !ok { + return &proto.HostInfo{ + Agent: agentVersion, + Boot: 0, + Hostname: "test-host", + DisplayName: "", + OsType: "", + Uuid: "", + Uname: "", + Partitons: []*proto.DiskPartition{}, + Network: &proto.Network{}, + Processor: []*proto.CpuInfo{}, + Release: &proto.ReleaseInfo{}, + } } + return returned } func (m *MockEnvironment) GetHostname() string { diff --git a/test/performance/vendor/modules.txt b/test/performance/vendor/modules.txt index 4ce9a6eca..3427d5afe 100644 --- a/test/performance/vendor/modules.txt +++ b/test/performance/vendor/modules.txt @@ -113,6 +113,7 @@ github.com/nats-io/nuid # github.com/nginx/agent/sdk/v2 v2.0.0-00010101000000-000000000000 => ./../../sdk ## explicit; go 1.18 github.com/nginx/agent/sdk/v2 +github.com/nginx/agent/sdk/v2/agent/config github.com/nginx/agent/sdk/v2/checksum github.com/nginx/agent/sdk/v2/client github.com/nginx/agent/sdk/v2/files diff --git a/test/utils/agent_config.go b/test/utils/agent_config.go index 80fd1a5bb..58fa133dd 100644 --- a/test/utils/agent_config.go +++ b/test/utils/agent_config.go @@ -9,7 +9,9 @@ import ( "github.com/spf13/viper" + agent_config "github.com/nginx/agent/sdk/v2/agent/config" "github.com/nginx/agent/v2/src/core/config" + sysutils "github.com/nginx/agent/v2/test/utils/system" log "github.com/sirupsen/logrus" ) @@ -116,7 +118,7 @@ func setupRoutine(wg *sync.WaitGroup) error { os.Clearenv() config.ROOT_COMMAND.ResetFlags() config.ROOT_COMMAND.ResetCommands() - config.Viper = viper.NewWithOptions(viper.KeyDelimiter(config.KeyDelimiter)) + config.Viper = viper.NewWithOptions(viper.KeyDelimiter(agent_config.KeyDelimiter)) config.SetDefaults() config.RegisterFlags() diff --git a/vendor/github.com/nginx/agent/sdk/v2/agent/config/config_helpers.go b/vendor/github.com/nginx/agent/sdk/v2/agent/config/config_helpers.go new file mode 100644 index 000000000..62e6492b5 --- /dev/null +++ b/vendor/github.com/nginx/agent/sdk/v2/agent/config/config_helpers.go @@ -0,0 +1,35 @@ +package config + +const ( + KeyDelimiter = "_" + + // viper keys used in config + FeaturesKey = "features" + FeatureRegistration = FeaturesKey + KeyDelimiter + "registration" + FeatureNginxConfig = FeaturesKey + KeyDelimiter + "nginx-config" + FeatureNginxConfigAsync = FeaturesKey + KeyDelimiter + "nginx-config-async" + FeatureNginxSSLConfig = FeaturesKey + KeyDelimiter + "nginx-ssl-config" + FeatureNginxCounting = FeaturesKey + KeyDelimiter + "nginx-counting" + FeatureMetrics = FeaturesKey + KeyDelimiter + "metrics" + FeatureMetricsThrottle = FeaturesKey + KeyDelimiter + "metrics-throttle" + FeatureDataPlaneStatus = FeaturesKey + KeyDelimiter + "dataplane-status" + FeatureProcessWatcher = FeaturesKey + KeyDelimiter + "process-watcher" + FeatureFileWatcher = FeaturesKey + KeyDelimiter + "file-watcher" + FeatureActivityEvents = FeaturesKey + KeyDelimiter + "activity-events" +) + +func GetDefaultFeatures() []string { + return []string{ + FeatureRegistration, + FeatureNginxConfig, + FeatureNginxSSLConfig, + FeatureNginxCounting, + FeatureNginxConfigAsync, + FeatureMetrics, + FeatureMetricsThrottle, + FeatureDataPlaneStatus, + FeatureProcessWatcher, + FeatureFileWatcher, + FeatureActivityEvents, + } +} diff --git a/vendor/github.com/nginx/agent/sdk/v2/proto/agent.pb.go b/vendor/github.com/nginx/agent/sdk/v2/proto/agent.pb.go index 61affae6b..f0335e02e 100644 --- a/vendor/github.com/nginx/agent/sdk/v2/proto/agent.pb.go +++ b/vendor/github.com/nginx/agent/sdk/v2/proto/agent.pb.go @@ -553,6 +553,7 @@ type AgentMeta struct { InstanceGroup string `protobuf:"bytes,5,opt,name=instance_group,json=instanceGroup,proto3" json:"instance_group"` Updated *types.Timestamp `protobuf:"bytes,6,opt,name=updated,proto3" json:"updated"` SystemUid string `protobuf:"bytes,7,opt,name=system_uid,json=systemUid,proto3" json:"system_uid"` + AgentDetails *AgentDetails `protobuf:"bytes,8,opt,name=agent_details,json=agentDetails,proto3" json:"agent_details"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -633,6 +634,13 @@ func (m *AgentMeta) GetSystemUid() string { return "" } +func (m *AgentMeta) GetAgentDetails() *AgentDetails { + if m != nil { + return m.AgentDetails + } + return nil +} + func init() { proto.RegisterEnum("f5.nginx.agent.sdk.AgentConnectStatus_StatusCode", AgentConnectStatus_StatusCode_name, AgentConnectStatus_StatusCode_value) proto.RegisterEnum("f5.nginx.agent.sdk.AgentLogging_Level", AgentLogging_Level_name, AgentLogging_Level_value) @@ -649,74 +657,75 @@ func init() { func init() { proto.RegisterFile("agent.proto", fileDescriptor_56ede974c0020f77) } var fileDescriptor_56ede974c0020f77 = []byte{ - // 1060 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xcd, 0x6e, 0x23, 0x45, - 0x10, 0xde, 0xf1, 0x4f, 0x6c, 0x97, 0xb3, 0xd9, 0x51, 0xef, 0x0a, 0xbc, 0x66, 0xc9, 0x58, 0x16, - 0x2c, 0x46, 0x82, 0x31, 0x78, 0x85, 0x10, 0x2c, 0x17, 0x3b, 0xf6, 0x66, 0x37, 0x1b, 0x6c, 0xd4, - 0x71, 0xb4, 0x12, 0x97, 0x51, 0xc7, 0xd3, 0x9e, 0x1d, 0xe2, 0x99, 0x36, 0xd3, 0xed, 0xe0, 0xec, - 0x23, 0xf0, 0x22, 0x5c, 0x78, 0x00, 0x1e, 0x80, 0x03, 0x47, 0x9e, 0xc0, 0x42, 0x39, 0xa1, 0x39, - 0x73, 0xe1, 0x86, 0xfa, 0x67, 0x12, 0x87, 0xfc, 0xc0, 0xa5, 0xbb, 0xea, 0xeb, 0xaa, 0xea, 0xaa, - 0xea, 0xaa, 0x9a, 0x81, 0x2a, 0x09, 0x68, 0x2c, 0xdc, 0x79, 0xc2, 0x04, 0x43, 0x68, 0xfa, 0x99, - 0x1b, 0x07, 0x61, 0xbc, 0x74, 0x35, 0xca, 0xfd, 0xe3, 0x3a, 0x04, 0x2c, 0x60, 0xfa, 0xbc, 0x0e, - 0xaf, 0x19, 0x37, 0xb2, 0xf5, 0xcd, 0x09, 0x8b, 0xa7, 0x61, 0x60, 0xb8, 0xaa, 0x56, 0xd3, 0x8c, - 0x13, 0x30, 0x16, 0xcc, 0x68, 0x5b, 0x71, 0x47, 0x8b, 0x69, 0x5b, 0x84, 0x11, 0xe5, 0x82, 0x44, - 0x73, 0x23, 0xf0, 0xd0, 0x9f, 0x7b, 0x9c, 0x4d, 0xc5, 0x0f, 0x24, 0xa1, 0x9e, 0x4f, 0x05, 0x09, - 0x67, 0x5c, 0x1f, 0x35, 0xff, 0xca, 0xc1, 0xfd, 0xae, 0xbc, 0x7c, 0x87, 0xc5, 0x31, 0x9d, 0x08, - 0x4c, 0xbf, 0x5f, 0x50, 0x2e, 0xd0, 0x53, 0x28, 0x44, 0x54, 0x90, 0x5a, 0xae, 0x61, 0xb5, 0xaa, - 0x9d, 0x77, 0xdd, 0xab, 0x9e, 0xba, 0x4a, 0xed, 0x6b, 0x2a, 0x48, 0xaf, 0x9c, 0xae, 0x1c, 0x25, - 0x8e, 0xd5, 0x8a, 0x76, 0xa1, 0x64, 0x6e, 0xa9, 0xe5, 0x1b, 0xf9, 0x56, 0xb5, 0xd3, 0xb8, 0x4e, - 0x7f, 0x28, 0xf9, 0xbe, 0x96, 0xeb, 0x55, 0xd3, 0x95, 0x93, 0x29, 0xe1, 0x8c, 0x40, 0x5f, 0x42, - 0x41, 0xa6, 0xa0, 0x56, 0x50, 0x5e, 0x3c, 0xba, 0xce, 0xca, 0x73, 0xc6, 0xc5, 0x8b, 0x78, 0xca, - 0xb4, 0x13, 0x52, 0x1a, 0xab, 0x15, 0xfd, 0x68, 0x41, 0xdd, 0x27, 0x82, 0xcc, 0x67, 0x24, 0xa6, - 0x57, 0xc2, 0xaf, 0x15, 0x95, 0x63, 0x1f, 0x5d, 0x67, 0xb2, 0x9f, 0x69, 0x1d, 0x18, 0xa5, 0xcc, - 0xc9, 0xed, 0x74, 0xe5, 0xdc, 0x62, 0x13, 0xd7, 0xfc, 0x1b, 0x34, 0xf7, 0x0a, 0x65, 0xcb, 0xce, - 0xe1, 0x72, 0xe8, 0xd3, 0x58, 0x84, 0xe2, 0xb4, 0xf9, 0x73, 0x0e, 0xd0, 0x7a, 0xda, 0x0f, 0x04, - 0x11, 0x0b, 0x8e, 0x8e, 0x00, 0xb8, 0xa2, 0x76, 0x98, 0x4f, 0x6b, 0x56, 0xc3, 0x6a, 0x6d, 0x75, - 0x3e, 0xbd, 0x31, 0xf7, 0x97, 0x74, 0xdd, 0x83, 0x73, 0xc5, 0xde, 0xbd, 0x74, 0xe5, 0x54, 0xb5, - 0x21, 0x6f, 0xc2, 0x7c, 0x8a, 0xd7, 0xac, 0xa2, 0xf7, 0xa1, 0x14, 0x51, 0xce, 0x49, 0x40, 0xd5, - 0xe3, 0x56, 0x74, 0xea, 0x0d, 0x84, 0x33, 0x02, 0x39, 0x50, 0xa4, 0x49, 0xc2, 0x92, 0x5a, 0x5e, - 0x09, 0x55, 0xd2, 0x95, 0xa3, 0x01, 0xac, 0xb7, 0xe6, 0x77, 0x00, 0x17, 0x57, 0xa2, 0xfb, 0x70, - 0x6f, 0x67, 0x34, 0x1c, 0x0e, 0x76, 0xc6, 0xde, 0xe1, 0xf0, 0xe5, 0x70, 0xf4, 0x6a, 0x68, 0xdf, - 0x41, 0x5b, 0x00, 0x19, 0x38, 0x7a, 0x69, 0x5b, 0xa8, 0x0e, 0x6f, 0x65, 0x3c, 0x1e, 0xec, 0x0d, - 0x76, 0xc6, 0x83, 0xbe, 0x37, 0x1a, 0x3f, 0x1f, 0x60, 0x3b, 0x87, 0xde, 0x81, 0xb7, 0xaf, 0x9c, - 0xf5, 0x0f, 0xbf, 0xf1, 0x5e, 0xf4, 0xed, 0x7c, 0xf3, 0x17, 0x0b, 0x1e, 0x5c, 0xae, 0x52, 0x3e, - 0x67, 0x31, 0xa7, 0x68, 0x0c, 0x9b, 0x2a, 0x29, 0x9e, 0xee, 0x0e, 0x95, 0xb2, 0x6a, 0xc7, 0xb9, - 0x2d, 0x65, 0xd3, 0x30, 0xe8, 0xd9, 0xe9, 0xca, 0xb9, 0xa4, 0x88, 0x75, 0x5f, 0xea, 0x63, 0xb4, - 0x07, 0x1b, 0x3a, 0x61, 0xa6, 0xfc, 0x1f, 0xff, 0xbf, 0x27, 0xe8, 0x41, 0xba, 0x72, 0x8c, 0x26, - 0x36, 0x7b, 0xf3, 0xc1, 0xc5, 0x43, 0xcb, 0x7b, 0x74, 0x7b, 0x35, 0xff, 0xb4, 0xa0, 0xba, 0x06, - 0xaf, 0x77, 0x8c, 0x0e, 0xa1, 0x71, 0xe3, 0x95, 0xb7, 0x77, 0xcc, 0x2e, 0x94, 0x66, 0x2c, 0x08, - 0x68, 0x92, 0xf9, 0x7e, 0xb3, 0xa1, 0x7d, 0x16, 0x04, 0x61, 0x1c, 0x68, 0x43, 0x46, 0x09, 0x67, - 0x84, 0x34, 0xa4, 0x53, 0xc3, 0x55, 0x05, 0xdc, 0x60, 0x28, 0x8b, 0x6a, 0xce, 0x12, 0xa1, 0x0d, - 0x19, 0x25, 0x9c, 0x11, 0xcd, 0x9f, 0x2c, 0xd8, 0x5c, 0x77, 0x1c, 0xb5, 0xa0, 0x3c, 0xa5, 0x44, - 0x2c, 0x12, 0x2a, 0x83, 0xcd, 0xb7, 0x2a, 0xbd, 0xcd, 0x74, 0xe5, 0x9c, 0x63, 0xf8, 0x9c, 0x42, - 0x2e, 0x00, 0x5d, 0x0a, 0x1a, 0xf3, 0x90, 0xc5, 0x32, 0x1e, 0x29, 0xbb, 0x95, 0xae, 0x9c, 0x35, - 0x14, 0xaf, 0xd1, 0xe8, 0x11, 0x14, 0x04, 0x09, 0xf4, 0xd0, 0xa9, 0xe8, 0x81, 0x20, 0x79, 0xac, - 0x56, 0x59, 0xd1, 0x64, 0x16, 0x12, 0xae, 0xa6, 0x89, 0xa9, 0x68, 0x05, 0x60, 0xbd, 0x35, 0xff, - 0xce, 0x19, 0x4f, 0x4d, 0x66, 0xd0, 0x2e, 0x14, 0x67, 0xf4, 0x84, 0xce, 0x4c, 0x27, 0x3e, 0xfe, - 0xaf, 0x54, 0xba, 0xfb, 0x52, 0x5a, 0x5b, 0x56, 0x8a, 0x58, 0x6f, 0xe8, 0x21, 0xe4, 0xfd, 0x30, - 0x31, 0xfd, 0x56, 0x4a, 0x57, 0x8e, 0x64, 0xb1, 0x5c, 0xa4, 0xcf, 0xd3, 0x70, 0x46, 0x4d, 0x9b, - 0x29, 0x9f, 0x25, 0x8f, 0xd5, 0x8a, 0x3e, 0x80, 0x72, 0x44, 0x96, 0x1e, 0x0f, 0xdf, 0x50, 0xe5, - 0xf6, 0x5d, 0x9d, 0xab, 0x0c, 0xc3, 0xa5, 0x88, 0x2c, 0x0f, 0xc2, 0x37, 0x14, 0x7d, 0x02, 0x55, - 0x09, 0x1e, 0x91, 0xc9, 0xf1, 0x62, 0x2e, 0xa7, 0x9b, 0x94, 0x55, 0x73, 0x60, 0x0d, 0xc6, 0x10, - 0x91, 0x65, 0x4f, 0xd3, 0xe8, 0x3d, 0x90, 0xca, 0x9e, 0x9c, 0x03, 0x1b, 0x4a, 0x5a, 0xcf, 0x01, - 0x0d, 0xe1, 0x8d, 0x88, 0x2c, 0xbb, 0x01, 0x95, 0x8f, 0x35, 0x61, 0xd1, 0x3c, 0xa1, 0x9c, 0xd7, - 0x4a, 0x0d, 0xab, 0x55, 0xd6, 0x0e, 0x64, 0x18, 0x3e, 0xa7, 0x9a, 0x5f, 0x41, 0x51, 0x85, 0x8f, - 0xca, 0x50, 0x78, 0x31, 0x7c, 0x36, 0xb2, 0xef, 0xa0, 0x0a, 0x14, 0xfb, 0x83, 0xde, 0xe1, 0xae, - 0x6d, 0x49, 0xf0, 0x55, 0x17, 0x0f, 0xed, 0x9c, 0x04, 0x07, 0x18, 0x8f, 0xb0, 0x9d, 0x97, 0xe4, - 0xb3, 0xee, 0xb8, 0xbb, 0x6f, 0x17, 0x9a, 0xbf, 0xe6, 0xa0, 0x72, 0xfe, 0x41, 0x91, 0x33, 0xea, - 0x84, 0x26, 0xf2, 0x51, 0x55, 0xea, 0xcd, 0x8c, 0x32, 0x10, 0xce, 0x08, 0xf4, 0x04, 0x36, 0xfd, - 0x90, 0xcf, 0x67, 0xe4, 0xd4, 0x8b, 0x49, 0x94, 0xcd, 0x33, 0xd5, 0xdc, 0xeb, 0x38, 0xae, 0x1a, - 0x6e, 0x48, 0x22, 0x2a, 0xdf, 0x42, 0x90, 0xc0, 0xd4, 0x88, 0x7a, 0x0b, 0x41, 0x02, 0x2c, 0x17, - 0xf4, 0x05, 0x6c, 0x85, 0x31, 0x17, 0x24, 0x9e, 0x50, 0x2f, 0x48, 0xd8, 0x62, 0xae, 0xf2, 0x58, - 0xe9, 0xa1, 0x74, 0xe5, 0xfc, 0xeb, 0x04, 0xdf, 0xcd, 0xf8, 0x5d, 0xc9, 0xa2, 0x2e, 0x94, 0x16, - 0x73, 0x9f, 0x08, 0xea, 0xab, 0x6c, 0x56, 0x3b, 0x75, 0x57, 0x7f, 0x95, 0xdd, 0xec, 0xab, 0xec, - 0x8e, 0xb3, 0xaf, 0xb2, 0x8e, 0xc6, 0x88, 0xe3, 0x8c, 0x40, 0x1f, 0x03, 0xf0, 0x53, 0x2e, 0x68, - 0xe4, 0x2d, 0x42, 0x5f, 0x25, 0xdb, 0x54, 0xfb, 0x05, 0x8a, 0x2b, 0x9a, 0x3e, 0x0c, 0xfd, 0xbd, - 0x42, 0xb9, 0x60, 0x17, 0x2f, 0xdc, 0x50, 0x91, 0xf6, 0x3e, 0xff, 0xed, 0x6c, 0xdb, 0xfa, 0xfd, - 0x6c, 0xdb, 0xfa, 0xe3, 0x6c, 0xdb, 0xfa, 0xf6, 0xc3, 0x20, 0x14, 0xaf, 0x17, 0x47, 0xee, 0x84, - 0x45, 0x6d, 0x55, 0xb7, 0x6d, 0x55, 0xb7, 0x6d, 0xee, 0x1f, 0xb7, 0x4f, 0x3a, 0xfa, 0x7f, 0xe1, - 0xa9, 0xf6, 0x6f, 0x43, 0x6d, 0x4f, 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0x02, 0x48, 0xb6, 0x2c, - 0xa0, 0x08, 0x00, 0x00, + // 1081 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xcd, 0x72, 0x1b, 0x45, + 0x10, 0xce, 0xea, 0xc7, 0x92, 0x5a, 0xb6, 0xb3, 0x4c, 0x52, 0xa0, 0x88, 0xe0, 0x55, 0xa9, 0x20, + 0x88, 0x2a, 0x58, 0x81, 0x52, 0x14, 0x05, 0xe1, 0x22, 0x59, 0x8a, 0x63, 0xc7, 0x48, 0xd4, 0x58, + 0xae, 0x50, 0x5c, 0xb6, 0xc6, 0xda, 0xd1, 0x66, 0xb1, 0x76, 0x57, 0xec, 0x8c, 0x8c, 0x9c, 0x47, + 0xe0, 0x21, 0xb8, 0x72, 0xe1, 0x01, 0x78, 0x04, 0x8e, 0x3c, 0xc1, 0x16, 0xe5, 0x13, 0xb5, 0x67, + 0x2e, 0xdc, 0xa8, 0xf9, 0x59, 0x5b, 0xc6, 0x3f, 0xc9, 0x65, 0xb6, 0xfb, 0x9b, 0xee, 0x9e, 0x9e, + 0x6f, 0xa6, 0x7b, 0x16, 0xaa, 0xc4, 0xa3, 0x21, 0xb7, 0xe7, 0x71, 0xc4, 0x23, 0x84, 0xa6, 0x9f, + 0xdb, 0xa1, 0xe7, 0x87, 0x4b, 0x5b, 0xa1, 0xcc, 0x3d, 0xae, 0x83, 0x17, 0x79, 0x91, 0x9a, 0xaf, + 0xc3, 0xcb, 0x88, 0x69, 0xdb, 0xfa, 0xfa, 0x24, 0x0a, 0xa7, 0xbe, 0xa7, 0xb5, 0xaa, 0x72, 0x53, + 0x8a, 0xe5, 0x45, 0x91, 0x37, 0xa3, 0x6d, 0xa9, 0x1d, 0x2d, 0xa6, 0x6d, 0xee, 0x07, 0x94, 0x71, + 0x12, 0xcc, 0xb5, 0xc1, 0x03, 0x77, 0xee, 0xb0, 0x68, 0xca, 0x7f, 0x22, 0x31, 0x75, 0x5c, 0xca, + 0x89, 0x3f, 0x63, 0x6a, 0xaa, 0xf9, 0x4f, 0x0e, 0xee, 0x75, 0xc5, 0xe2, 0xdb, 0x51, 0x18, 0xd2, + 0x09, 0xc7, 0xf4, 0xc7, 0x05, 0x65, 0x1c, 0x3d, 0x81, 0x42, 0x40, 0x39, 0xa9, 0xe5, 0x1a, 0x46, + 0xab, 0xda, 0x79, 0xcf, 0xbe, 0x9a, 0xa9, 0x2d, 0xdd, 0xbe, 0xa1, 0x9c, 0xf4, 0xca, 0x69, 0x62, + 0x49, 0x73, 0x2c, 0x47, 0xb4, 0x03, 0x25, 0xbd, 0x4a, 0x2d, 0xdf, 0xc8, 0xb7, 0xaa, 0x9d, 0xc6, + 0x75, 0xfe, 0x43, 0xa1, 0xf7, 0x95, 0x5d, 0xaf, 0x9a, 0x26, 0x56, 0xe6, 0x84, 0x33, 0x01, 0x7d, + 0x05, 0x05, 0x41, 0x41, 0xad, 0x20, 0xb3, 0x78, 0x78, 0x5d, 0x94, 0x67, 0x11, 0xe3, 0xbb, 0xe1, + 0x34, 0x52, 0x49, 0x08, 0x6b, 0x2c, 0x47, 0xf4, 0xb3, 0x01, 0x75, 0x97, 0x70, 0x32, 0x9f, 0x91, + 0x90, 0x5e, 0xd9, 0x7e, 0xad, 0x28, 0x13, 0xfb, 0xf8, 0xba, 0x90, 0xfd, 0xcc, 0xeb, 0x40, 0x3b, + 0x65, 0x49, 0x6e, 0xa5, 0x89, 0x75, 0x4b, 0x4c, 0x5c, 0x73, 0x6f, 0xf0, 0xdc, 0x2b, 0x94, 0x0d, + 0x33, 0x87, 0xcb, 0xbe, 0x4b, 0x43, 0xee, 0xf3, 0xd3, 0xe6, 0x6f, 0x39, 0x40, 0xab, 0xb4, 0x1f, + 0x70, 0xc2, 0x17, 0x0c, 0x1d, 0x01, 0x30, 0x29, 0x6d, 0x47, 0x2e, 0xad, 0x19, 0x0d, 0xa3, 0xb5, + 0xd9, 0xf9, 0xec, 0x46, 0xee, 0x2f, 0xf9, 0xda, 0x07, 0xe7, 0x8e, 0xbd, 0xbb, 0x69, 0x62, 0x55, + 0x55, 0x20, 0x67, 0x12, 0xb9, 0x14, 0xaf, 0x44, 0x45, 0x1f, 0x40, 0x29, 0xa0, 0x8c, 0x11, 0x8f, + 0xca, 0xc3, 0xad, 0x28, 0xea, 0x35, 0x84, 0x33, 0x01, 0x59, 0x50, 0xa4, 0x71, 0x1c, 0xc5, 0xb5, + 0xbc, 0x34, 0xaa, 0xa4, 0x89, 0xa5, 0x00, 0xac, 0x3e, 0xcd, 0x1f, 0x00, 0x2e, 0x96, 0x44, 0xf7, + 0xe0, 0xee, 0xf6, 0x68, 0x38, 0x1c, 0x6c, 0x8f, 0x9d, 0xc3, 0xe1, 0xf3, 0xe1, 0xe8, 0xc5, 0xd0, + 0xbc, 0x83, 0x36, 0x01, 0x32, 0x70, 0xf4, 0xdc, 0x34, 0x50, 0x1d, 0xde, 0xce, 0x74, 0x3c, 0xd8, + 0x1b, 0x6c, 0x8f, 0x07, 0x7d, 0x67, 0x34, 0x7e, 0x36, 0xc0, 0x66, 0x0e, 0xbd, 0x0b, 0xef, 0x5c, + 0x99, 0xeb, 0x1f, 0x7e, 0xeb, 0xec, 0xf6, 0xcd, 0x7c, 0xf3, 0x77, 0x03, 0xee, 0x5f, 0xbe, 0xa5, + 0x6c, 0x1e, 0x85, 0x8c, 0xa2, 0x31, 0xac, 0x4b, 0x52, 0x1c, 0x55, 0x1d, 0x92, 0xb2, 0x6a, 0xc7, + 0xba, 0x8d, 0xb2, 0xa9, 0xef, 0xf5, 0xcc, 0x34, 0xb1, 0x2e, 0x39, 0x62, 0x55, 0x97, 0x6a, 0x1a, + 0xed, 0xc1, 0x9a, 0x22, 0x4c, 0x5f, 0xff, 0x47, 0x6f, 0x76, 0x04, 0x3d, 0x48, 0x13, 0x4b, 0x7b, + 0x62, 0xfd, 0x6d, 0xde, 0xbf, 0x38, 0x68, 0xb1, 0x8e, 0x2a, 0xaf, 0xe6, 0xdf, 0x06, 0x54, 0x57, + 0xe0, 0xd5, 0x8a, 0x51, 0x5b, 0x68, 0xdc, 0xb8, 0xe4, 0xed, 0x15, 0xb3, 0x03, 0xa5, 0x59, 0xe4, + 0x79, 0x34, 0xce, 0x72, 0xbf, 0x39, 0xd0, 0x7e, 0xe4, 0x79, 0x7e, 0xe8, 0xa9, 0x40, 0xda, 0x09, + 0x67, 0x82, 0x08, 0xa4, 0xa8, 0x61, 0xf2, 0x06, 0xdc, 0x10, 0x28, 0xdb, 0xd5, 0x3c, 0x8a, 0xb9, + 0x0a, 0xa4, 0x9d, 0x70, 0x26, 0x34, 0x7f, 0x35, 0x60, 0x7d, 0x35, 0x71, 0xd4, 0x82, 0xf2, 0x94, + 0x12, 0xbe, 0x88, 0xa9, 0xd8, 0x6c, 0xbe, 0x55, 0xe9, 0xad, 0xa7, 0x89, 0x75, 0x8e, 0xe1, 0x73, + 0x09, 0xd9, 0x00, 0x74, 0xc9, 0x69, 0xc8, 0xfc, 0x28, 0x14, 0xfb, 0x11, 0xb6, 0x9b, 0x69, 0x62, + 0xad, 0xa0, 0x78, 0x45, 0x46, 0x0f, 0xa1, 0xc0, 0x89, 0xa7, 0x9a, 0x4e, 0x45, 0x35, 0x04, 0xa1, + 0x63, 0x39, 0x8a, 0x1b, 0x4d, 0x66, 0x3e, 0x61, 0xb2, 0x9b, 0xe8, 0x1b, 0x2d, 0x01, 0xac, 0x3e, + 0xcd, 0x7f, 0x73, 0x3a, 0x53, 0xcd, 0x0c, 0xda, 0x81, 0xe2, 0x8c, 0x9e, 0xd0, 0x99, 0xae, 0xc4, + 0x47, 0xaf, 0xa3, 0xd2, 0xde, 0x17, 0xd6, 0x2a, 0xb2, 0x74, 0xc4, 0xea, 0x83, 0x1e, 0x40, 0xde, + 0xf5, 0x63, 0x5d, 0x6f, 0xa5, 0x34, 0xb1, 0x84, 0x8a, 0xc5, 0x20, 0x72, 0x9e, 0xfa, 0x33, 0xaa, + 0xcb, 0x4c, 0xe6, 0x2c, 0x74, 0x2c, 0x47, 0xf4, 0x21, 0x94, 0x03, 0xb2, 0x74, 0x98, 0xff, 0x8a, + 0xca, 0xb4, 0x37, 0x14, 0x57, 0x19, 0x86, 0x4b, 0x01, 0x59, 0x1e, 0xf8, 0xaf, 0x28, 0xfa, 0x14, + 0xaa, 0x02, 0x3c, 0x22, 0x93, 0xe3, 0xc5, 0x5c, 0x74, 0x37, 0x61, 0x2b, 0xfb, 0xc0, 0x0a, 0x8c, + 0x21, 0x20, 0xcb, 0x9e, 0x92, 0xd1, 0xfb, 0x20, 0x9c, 0x1d, 0xd1, 0x07, 0xd6, 0xa4, 0xb5, 0xea, + 0x03, 0x0a, 0xc2, 0x6b, 0x01, 0x59, 0x76, 0x3d, 0x2a, 0x0e, 0x6b, 0x12, 0x05, 0xf3, 0x98, 0x32, + 0x56, 0x2b, 0x35, 0x8c, 0x56, 0x59, 0x25, 0x90, 0x61, 0xf8, 0x5c, 0x6a, 0x7e, 0x0d, 0x45, 0xb9, + 0x7d, 0x54, 0x86, 0xc2, 0xee, 0xf0, 0xe9, 0xc8, 0xbc, 0x83, 0x2a, 0x50, 0xec, 0x0f, 0x7a, 0x87, + 0x3b, 0xa6, 0x21, 0xc0, 0x17, 0x5d, 0x3c, 0x34, 0x73, 0x02, 0x1c, 0x60, 0x3c, 0xc2, 0x66, 0x5e, + 0x88, 0x4f, 0xbb, 0xe3, 0xee, 0xbe, 0x59, 0x68, 0xfe, 0x92, 0x87, 0xca, 0xf9, 0x83, 0x22, 0x7a, + 0xd4, 0x09, 0x8d, 0xc5, 0xa1, 0x4a, 0xea, 0x75, 0x8f, 0xd2, 0x10, 0xce, 0x04, 0xf4, 0x18, 0xd6, + 0x5d, 0x9f, 0xcd, 0x67, 0xe4, 0xd4, 0x09, 0x49, 0x90, 0xf5, 0x33, 0x59, 0xdc, 0xab, 0x38, 0xae, + 0x6a, 0x6d, 0x48, 0x02, 0x2a, 0xce, 0x82, 0x13, 0x4f, 0xdf, 0x11, 0x79, 0x16, 0x9c, 0x78, 0x58, + 0x0c, 0xe8, 0x4b, 0xd8, 0xf4, 0x43, 0xc6, 0x49, 0x38, 0xa1, 0x8e, 0x17, 0x47, 0x8b, 0xb9, 0xe4, + 0xb1, 0xd2, 0x43, 0x69, 0x62, 0xfd, 0x6f, 0x06, 0x6f, 0x64, 0xfa, 0x8e, 0x50, 0x51, 0x17, 0x4a, + 0x8b, 0xb9, 0x4b, 0x38, 0x75, 0x25, 0x9b, 0xd5, 0x4e, 0xdd, 0x56, 0xaf, 0xb2, 0x9d, 0xbd, 0xca, + 0xf6, 0x38, 0x7b, 0x95, 0xd5, 0x6e, 0xb4, 0x39, 0xce, 0x04, 0xf4, 0x09, 0x00, 0x3b, 0x65, 0x9c, + 0x06, 0xce, 0xc2, 0x77, 0x25, 0xd9, 0xfa, 0xb6, 0x5f, 0xa0, 0xb8, 0xa2, 0xe4, 0x43, 0xdf, 0x45, + 0xdf, 0xc1, 0x86, 0xea, 0x60, 0x59, 0xe3, 0x28, 0xbf, 0x61, 0xe3, 0x78, 0x2b, 0x4d, 0xac, 0xcb, + 0xae, 0x58, 0xf5, 0xc2, 0x8b, 0xc7, 0xaa, 0x60, 0x16, 0x2f, 0x36, 0x28, 0x39, 0xec, 0x7d, 0xf1, + 0xc7, 0xd9, 0x96, 0xf1, 0xe7, 0xd9, 0x96, 0xf1, 0xd7, 0xd9, 0x96, 0xf1, 0xfd, 0x47, 0x9e, 0xcf, + 0x5f, 0x2e, 0x8e, 0xec, 0x49, 0x14, 0xb4, 0xe5, 0x62, 0x6d, 0x19, 0xa1, 0xcd, 0xdc, 0xe3, 0xf6, + 0x49, 0x47, 0xfd, 0x89, 0x3c, 0x51, 0x3b, 0x5f, 0x93, 0x9f, 0xc7, 0xff, 0x05, 0x00, 0x00, 0xff, + 0xff, 0xb4, 0x95, 0x5a, 0x2d, 0xfa, 0x08, 0x00, 0x00, } func (m *AgentConnectRequest) Marshal() (dAtA []byte, err error) { @@ -1141,6 +1150,18 @@ func (m *AgentMeta) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.AgentDetails != nil { + { + size, err := m.AgentDetails.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAgent(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } if len(m.SystemUid) > 0 { i -= len(m.SystemUid) copy(dAtA[i:], m.SystemUid) @@ -1416,6 +1437,10 @@ func (m *AgentMeta) Size() (n int) { if l > 0 { n += 1 + l + sovAgent(uint64(l)) } + if m.AgentDetails != nil { + l = m.AgentDetails.Size() + n += 1 + l + sovAgent(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -2701,6 +2726,42 @@ func (m *AgentMeta) Unmarshal(dAtA []byte) error { } m.SystemUid = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AgentDetails", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAgent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAgent + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAgent + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AgentDetails == nil { + m.AgentDetails = &AgentDetails{} + } + if err := m.AgentDetails.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAgent(dAtA[iNdEx:]) diff --git a/vendor/github.com/nginx/agent/sdk/v2/proto/agent.proto b/vendor/github.com/nginx/agent/sdk/v2/proto/agent.proto index 92894732f..7aa32e2e0 100644 --- a/vendor/github.com/nginx/agent/sdk/v2/proto/agent.proto +++ b/vendor/github.com/nginx/agent/sdk/v2/proto/agent.proto @@ -78,4 +78,5 @@ message AgentMeta { string instance_group = 5 [(gogoproto.jsontag) = "instance_group"]; google.protobuf.Timestamp updated = 6 [(gogoproto.jsontag) = "updated"]; string system_uid = 7 [(gogoproto.jsontag) = "system_uid"]; + AgentDetails agent_details = 8 [(gogoproto.jsontag) = "agent_details"]; } diff --git a/vendor/github.com/nginx/agent/sdk/v2/proto/metrics.svc.proto b/vendor/github.com/nginx/agent/sdk/v2/proto/metrics.svc.proto index 2b84942f1..81959dda8 100644 --- a/vendor/github.com/nginx/agent/sdk/v2/proto/metrics.svc.proto +++ b/vendor/github.com/nginx/agent/sdk/v2/proto/metrics.svc.proto @@ -7,10 +7,6 @@ import "events/event.proto"; import "metrics.proto"; // MetricsService is responsible for ingesting high volume metrics and events -// Note: -// The naming of MetricsService is unfortunate, it is extended to StreamEvents -// to keep backward and forward compatability with NGINX Management Suite products -// This will be refactored when a major revision change for NGINX Agent is introduced service MetricsService { // A client-to-server streaming RPC to deliver high volume metrics reports. rpc Stream(stream MetricsReport) returns (google.protobuf.Empty) {} diff --git a/vendor/modules.txt b/vendor/modules.txt index 369d5dd82..44115efc1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -115,6 +115,7 @@ github.com/mwitkow/go-proto-validators/protoc-gen-govalidators # github.com/nginx/agent/sdk/v2 v2.0.0-00010101000000-000000000000 => ./sdk ## explicit; go 1.18 github.com/nginx/agent/sdk/v2 +github.com/nginx/agent/sdk/v2/agent/config github.com/nginx/agent/sdk/v2/checksum github.com/nginx/agent/sdk/v2/client github.com/nginx/agent/sdk/v2/files