5 #include "http_parser/http_parser.h"
7 #include <boost/uuid/uuid_io.hpp>
8 #include <boost/algorithm/string/case_conv.hpp>
12 #include <vnc_cfg_types.h>
13 #include <agent_types.h>
37 (
"/usr/bin/contrail-vrouter-agent-health-check.py");
44 bool ignore_status_event) :
45 service_(NULL), intf_(intf),
47 last_update_time_(
"-"), deleted_(false),
48 ignore_status_event_(ignore_status_event) {
53 ip_->set_active(
true);
62 if (!
service_.get()->IsVnIpListHealthCheckService()) {
101 std::string str(
"Instance for service ");
103 str +=
" interface " +
intf_->name();
112 service_->table()->InstanceEventEnqueue(event);
119 service_->table()->InstanceEventEnqueue(event);
148 return ip_->service_ip();
154 return ip_->destination_ip();
159 ip_->set_destination_ip(ip);
168 bool ignore_status_event) :
177 if (
task_.get() != NULL) {
186 service_->table()->agent()->event_manager()));
187 if (
task_.get() != NULL) {
188 task_->set_pipe_stdout(
true);
189 task_->set_on_data_cb(
191 task_->set_on_exit_cb(
204 if (
task_.get() == NULL) {
225 if (
service_->table()->agent()->test_mode()) {
227 task_->set_cmd(
"sleep 1");
231 std::stringstream cmd_str;
233 cmd_str <<
" -d " <<
ip_->GetLinkLocalIp().to_string();
234 cmd_str <<
" -t " <<
service_->timeout() +
235 service_->timeout_usecs() / 1000000;
236 cmd_str <<
" -r " <<
service_->max_retries();
237 cmd_str <<
" -i " <<
service_->delay() +
240 if (
service_->monitor_type().find(
"HTTP") != std::string::npos &&
243 cmd_str <<
" -u " <<
service_->url_path();
246 task_->set_cmd(cmd_str.str());
250 return (
task_.get() != NULL ?
task_->is_running():
false);
260 other_intf_(other_intf), multi_hop_(multi_hop) {
280 if (
service_->table()->health_check_service_callback(type).empty() ||
281 service_->table()->health_check_service_callback(type)
295 if (!
service_->table()->health_check_service_callback(type).empty()) {
297 service_->table()->health_check_service_callback(type)
307 if (!
service_->table()->health_check_service_callback(type).empty()) {
311 return service_->table()->health_check_service_callback(type)
320 if (!
service_->table()->health_check_service_callback(type).empty()) {
322 return service_->table()->health_check_service_callback(type)
329 bool success =
false;
331 if (!
service_->table()->health_check_service_callback(type).empty()) {
335 success =
service_->table()->health_check_service_callback(type)
357 ignore_status_event, multi_hop) {
370 if (!
service_->table()->health_check_notify_callback().empty()) {
371 service_->table()->health_check_notify_callback()(
this);
381 instance_(inst), service_(service), type_(type), message_(message) {
427 std::string &name)
const {
428 HealthCheckSandeshResp *resp =
static_cast<HealthCheckSandeshResp *
>(sresp);
430 HealthCheckSandeshData data;
432 data.set_name(
name_);
444 std::vector<HealthCheckInstanceSandeshData> inst_list;
445 InstanceList::const_iterator it =
intf_list_.begin();
447 HealthCheckInstanceSandeshData inst_data;
449 inst_data.set_metadata_ip
450 (it->second->ip()->GetLinkLocalIp().to_string());
451 inst_data.set_service_ip(it->second->source_ip().to_string());
452 inst_data.set_health_check_ip
453 (it->second->destination_ip().to_string());
454 inst_data.set_active(it->second->active());
455 inst_data.set_running(it->second->IsRunning());
456 inst_data.set_last_update_time(it->second->last_update_time());
457 inst_list.push_back(inst_data);
460 data.set_inst_list(inst_list);
462 std::vector<HealthCheckSandeshData> &list =
463 const_cast<std::vector<HealthCheckSandeshData>&
>(resp->get_hc_list());
464 list.push_back(data);
482 return (
service_type_.find(
"vn-ip-list") != std::string::npos);
491 bool ignore_status_event,
498 intrface, ignore_status_event);
502 intrface, paired_vmi, ignore_status_event, multi_hop);
509 intrface, paired_vmi, ignore_status_event, multi_hop);
543 bool dest_ip_changed =
false;
544 bool service_type_changed =
false;
545 bool monitor_type_changed =
false;
552 monitor_type_changed =
true;
558 service_type_changed =
true;
629 dest_ip_changed =
true;
638 if ((service_type_changed &&
640 (monitor_type_changed &&
647 InstanceList::iterator it =
intf_list_.begin();
649 it->second->StopInstanceTask();
662 std::set<boost::uuids::uuid>::iterator it_cfg =
664 InstanceList::iterator it =
intf_list_.begin();
668 ((it !=
intf_list_.end()) && ((*it_cfg) > it->first))) {
669 InstanceList::iterator it_prev = it;
675 if ((it ==
intf_list_.end()) || ((*it_cfg) < it->first)) {
691 if (paired_vmi == NULL) {
697 if (destination_ip.is_unspecified()) {
720 it->second->set_destination_ip(
dest_ip_);
732 InstanceList::iterator it =
intf_list_.begin();
734 it->second->set_service(
this);
752 InstanceList::iterator it;
757 it->second->EnqueueHealthCheckResync(service, intf);
765 InstanceList::iterator it;
769 it->second->set_service(
this);
776 InstanceList::iterator it =
intf_list_.begin();
787 const std::string &name) :
802 const std::string &name) {
805 (
static_cast<DBTable *
>(health_check_table))->Init();
806 return health_check_table;
809 std::unique_ptr<DBEntry>
814 return std::unique_ptr<DBEntry>(
static_cast<DBEntry *
>(service));
823 service->
Copy(
this, data);
842 ret |= service->
Copy(
this, data);
874 const autogen::ServiceHealthCheck *s) {
875 boost::system::error_code ec;
876 const autogen::ServiceHealthCheckType &p = s->properties();
878 std::string url_path;
879 uint8_t ip_proto = 0;
880 uint16_t url_port = 0;
881 if (p.monitor_type.find(
"BFD") != std::string::npos) {
882 boost::system::error_code ec;
883 dest_ip = Ip4Address::from_string(p.url_path, ec);
884 url_path = p.url_path;
885 ip_proto = IPPROTO_UDP;
886 }
else if (p.monitor_type.find(
"HTTP") == std::string::npos) {
887 boost::system::error_code ec;
888 dest_ip = Ip4Address::from_string(p.url_path, ec);
889 url_path = p.url_path;
890 ip_proto = IPPROTO_ICMP;
891 }
else if (!p.url_path.empty()) {
892 ip_proto = IPPROTO_TCP;
894 struct http_parser_url urldata;
895 int ret = http_parser_parse_url(p.url_path.c_str(), p.url_path.size(),
898 if (urldata.field_set & (1 << UF_HOST)) {
899 std::string dest_ip_str =
900 p.url_path.substr(urldata.field_data[UF_HOST].off,
901 urldata.field_data[UF_HOST].len);
903 dest_ip = Ip4Address::from_string(dest_ip_str, ec);
905 url_path = p.url_path.substr(urldata.field_data[UF_HOST].off +\
906 urldata.field_data[UF_HOST].len);
908 url_port = urldata.port;
909 if ((urldata.field_set & (1 << UF_PORT)) == 0) {
915 bool is_all_ip =
false;
916 if (p.target_ip_all) {
919 std::set<IpAddress> ip_address_list;
920 for (
unsigned int i = 0; i < p.target_ip_list.ip_address.size(); ++i) {
921 boost::system::error_code ec;
922 IpAddress ip = Ip4Address::from_string(p.target_ip_list.ip_address[i], ec);
923 if (ec.value() != 0) {
924 ip = Ip6Address::from_string(p.target_ip_list.ip_address[i], ec);
926 if (ec.value() != 0) {
930 ip_address_list.insert(ip);
935 p.monitor_type, p.health_check_type,
936 ip_proto, p.http_method,
937 url_path, url_port, p.expected_codes,
938 p.delay, p.delayUsecs, p.timeout,
939 p.timeoutUsecs, p.max_retries,
940 is_all_ip, ip_address_list, node);
944 node->
begin(table->GetGraph());
945 iter != node->
end(table->GetGraph()); ++iter) {
953 autogen::VirtualMachineInterface *intf =
954 dynamic_cast<autogen::VirtualMachineInterface *
>(adj_node->
GetObject());
956 const autogen::IdPermsType &id_perms = intf->id_perms();
958 id_perms.uuid.uuid_lslong, intf_uuid);
964 autogen::VirtualNetwork *vn =
965 dynamic_cast<autogen::VirtualNetwork *
>(adj_node->
GetObject());
967 const autogen::IdPermsType &id_perms = vn->id_perms();
969 id_perms.uuid.uuid_lslong, vn_uuid);
979 autogen::ServiceHealthCheck *service =
980 static_cast<autogen::ServiceHealthCheck *
>(node->
GetObject());
997 autogen::ServiceHealthCheck *service =
998 static_cast <autogen::ServiceHealthCheck *>(node->
GetObject());
1015 autogen::ServiceHealthCheck *service =
1016 static_cast<autogen::ServiceHealthCheck *
>(node->
GetObject());
1017 autogen::IdPermsType id_perms = service->id_perms();
1018 CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong, u);
1035 switch (event->
type_) {
1042 "Read Event while deleted! " + inst->
to_string());
1048 std::string msg =
event->message_;
1049 boost::algorithm::to_lower(msg);
1050 if (msg.find(
"success") != std::string::npos) {
1056 if (msg.find(
"failure") != std::string::npos) {
1063 " Received msg = " +
event->message_);
1103 const std::string &context) {
1108 void HealthCheckSandeshReq::HandleRequest()
const {
1110 sand->DoSandesh(sand);
void ResyncHealthCheckInterface(const HealthCheckService *service, const VmInterface *intf)
virtual bool OperDBDelete(DBEntry *entry, const DBRequest *req)
InterfaceRef interface() const
virtual void ResyncTarget(const HealthCheckService *service) const
virtual ~HealthCheckInstanceEvent()
virtual bool IFNodeToUuid(IFMapNode *node, boost::uuids::uuid &u)
virtual bool OperDBOnChange(DBEntry *entry, const DBRequest *req)
virtual bool DestroyInstanceTask()=0
void EnqueueResync(const HealthCheckService *service, Interface *itf) const
bool DBEntrySandesh(Sandesh *resp, std::string &name) const
bool InstanceEventProcess(HealthCheckInstanceEvent *event)
HealthCheckService(const HealthCheckTable *table, const boost::uuids::uuid &id)
virtual AgentSandeshPtr GetAgentSandesh(const AgentSandeshArguments *args, const std::string &context)
static void CfgUuidSet(uint64_t ms_long, uint64_t ls_long, boost::uuids::uuid &u)
void set_source_ip(const IpAddress &ip)
void Shutdown(bool delete_entries=true)
std::set< boost::uuids::uuid > vn_uuid_list_
virtual bool StopInstanceTask()
virtual bool DestroyInstanceTask()
#define HEALTH_CHECK_TRACE(obj,...)
void AddHealthCheckServiceNode(IFMapNode *node)
std::string GetString(const std::string &key) const
const boost::uuids::uuid & GetUuid() const
HealthCheckService * service() const
HealthCheckInstanceService(HealthCheckService *service, MetaDataIpAllocator *allocator, VmInterface *intf, VmInterface *other_intf, bool ignore_status_event, bool multi_hop)
bool ProcessConfig(IFMapNode *node, DBRequest &req, const boost::uuids::uuid &u)
IpAddress destination_ip() const
virtual bool IFNodeToReq(IFMapNode *node, DBRequest &req, const boost::uuids::uuid &u)
virtual ~HealthCheckMacIpInstanceService()
HealthCheckType health_check_type_
void UpdateInstanceTaskCommand()
void InsertHealthCheckInstance(HealthCheckInstanceBase *hc_inst)
void UpdateInterfaceInstanceServiceReference(const VmInterface *intf)
ConfigManager * config_manager() const
void StopTask(HealthCheckService *service)
std::set< IpAddress > new_target_ip_list_
boost::asio::ip::address IpAddress
virtual void ResyncTarget(const HealthCheckService *service) const
virtual ~HealthCheckTable()
std::unique_ptr< DBRequestData > data
const HealthCheckTable * table() const
HealthCheckService * service_
AgentDBEntry * FindActiveEntry(const DBEntry *key)
InterfaceTable * interface_table() const
bool Enqueue(DBRequest *req)
virtual bool RunInstanceTask()=0
WorkQueue< HealthCheckInstanceEvent * > * inst_event_queue_
HealthCheckMacIpInstanceService(HealthCheckService *service, MetaDataIpAllocator *allocator, VmInterface *intf, VmInterface *other_intf, bool ignore_status_event, bool multi_hop)
adjacency_iterator end(DBGraph *graph)
static std::string UuidToString(const boost::uuids::uuid &id)
void set_destination_ip(const IpAddress &ip)
virtual std::string ToString() const
virtual std::unique_ptr< DBEntry > AllocEntry(const DBRequestKey *k) const
virtual ~HealthCheckInstanceService()
boost::scoped_ptr< MetaDataIp > ip_
IpAddress GetServiceIp(const IpAddress &ip) const
boost::shared_ptr< TraceBuffer< SandeshTrace > > SandeshTraceBufferPtr
void set_service(HealthCheckService *service)
std::unique_ptr< DBRequestKey > KeyPtr
virtual bool UpdateInstanceTask()
HealthCheckInstanceTask(HealthCheckService *service, MetaDataIpAllocator *allocator, VmInterface *intf, bool ignore_status_event)
std::string monitor_type_
virtual bool OperDBResync(DBEntry *entry, const DBRequest *req)
int GetTaskId(const std::string &name)
const VmInterface * intf_
virtual DBEntry * OperDBAdd(const DBRequest *req)
void StopHealthCheckService(HealthCheckInstanceBase *instance)
HealthCheckTable(Agent *agent, DB *db, const std::string &name)
virtual bool StopInstanceTask()
static const std::string kHealthCheckCmd
MetaDataIpAllocator * metadata_ip_allocator() const
IFMapAgentTable * cfg_vm_interface_table() const
const HealthCheckTable * table_
virtual ~HealthCheckInstanceTask()
TaskScheduler * task_scheduler() const
virtual void SetKey(const DBRequestKey *key)
bool IsSegmentHealthCheckService() const
HealthCheckServiceRef service_
std::unique_ptr< DBRequestKey > key
void InstanceEventEnqueue(HealthCheckInstanceEvent *event) const
void OnExit(const boost::system::error_code &ec)
void SetService(HealthCheckService *service)
virtual KeyPtr GetDBRequestKey() const
virtual bool IsLess(const DBEntry &rhs) const
HealthCheckInstanceEvent(HealthCheckInstanceBase *inst, HealthCheckService *service, EventType type, const std::string &message)
static HealthCheckServiceData * BuildData(Agent *agent, IFMapNode *node, const autogen::ServiceHealthCheck *s)
class boost::shared_ptr< AgentSandesh > AgentSandeshPtr
AgentDBEntry * Find(const DBEntry *key, bool ret_del)
std::string expected_codes_
virtual bool UpdateInstanceTask()
IpAddress source_ip() const
InstanceTaskExecvp HeathCheckProcessInstance
const std::string & name() const
std::set< boost::uuids::uuid > vn_uuid_list_
boost::asio::ip::address_v4 Ip4Address
HealthCheckInstanceBase * StartHealthCheckService(VmInterface *intrface, VmInterface *paired_vmi, const IpAddress &source_ip, const IpAddress &destination_ip, const MacAddress &destination_mac, bool ignore_status_event, bool multi_hop)
std::string service_type_
static DBTableBase * CreateTable(Agent *agent, DB *db, const std::string &name)
void DeleteHealthCheckInstance(HealthCheckInstanceBase *hc_inst)
const Ip4Address & primary_ip_addr() const
const boost::uuids::uuid & uuid() const
IFMapObject * GetObject()
HealthCheckInstanceBase(HealthCheckService *service, MetaDataIpAllocator *allocator, VmInterface *intf, bool ignore_status_event)
virtual void ResyncTarget(const HealthCheckService *service) const
bool Copy(HealthCheckTable *table, const HealthCheckServiceData *data)
HealthCheckTable * health_check_table() const
HealthCheckService * Find(const boost::uuids::uuid &u)
static uint64_t UTCTimestampUsec()
void EnqueueHealthCheckResync(const HealthCheckService *service, const VmInterface *itf) const
std::string expected_codes_
virtual bool CreateInstanceTask()
IpAddress update_source_ip()
const boost::uuids::uuid & vmi_cfg_uuid() const
static HealthCheckServiceKey * BuildKey(const boost::uuids::uuid &u)
SandeshTraceBufferPtr HealthCheckTraceBuf
bool is_hc_enable_all_ip_
std::set< IpAddress > target_ip_list_
std::string last_update_time_
virtual void set_destination_mac(const MacAddress &mac)
std::set< boost::uuids::uuid > intf_uuid_list_
const std::string & name() const
std::string monitor_type_
IFMapAgentTable * cfg_vn_table() const
VmInterface * PortTuplePairedInterface() const
IpAddress GetGatewayIp(const IpAddress &ip) const
bool IsVnIpListHealthCheckService() const
bool IsInstanceTaskBased() const
AgentConfig * cfg() const
virtual bool RunInstanceTask()
void OnRead(const std::string &data)
bool SkipNode(IFMapNode *node)
std::string service_type_
void UpdateInstanceServiceReference()
virtual bool DestroyInstanceTask()
virtual bool IsRunning() const
adjacency_iterator begin(DBGraph *graph)
HealthCheckType GetHealthCheckType() const
virtual ~HealthCheckInstanceBase()
bool Enqueue(QueueEntryT entry)
void set_name(const std::string &name)
IpAddress destination_ip_
virtual bool RunInstanceTask()
bool IsStatusEventIgnored() const
virtual bool CreateInstanceTask()=0
void set_agent(Agent *agent)
SandeshTraceBufferPtr SandeshTraceBufferCreate(const std::string &buf_name, size_t buf_size, bool trace_enable=true)
static std::string UTCUsecToString(uint64_t tstamp)
virtual bool CreateInstanceTask()