int EndpointDbObject::EndpointIsConnected(const Endpoint::Ptr& endpoint) { unsigned int is_connected = endpoint->IsConnected() ? 1 : 0; /* if identity is equal to node, fake is_connected */ if (endpoint->GetName() == IcingaApplication::GetInstance()->GetNodeName()) is_connected = 1; return is_connected; }
Value EndpointsTable::IsConnectedAccessor(const Value& row) { Endpoint::Ptr endpoint = static_cast<Endpoint::Ptr>(row); if (!endpoint) return Empty; unsigned int is_connected = endpoint->IsConnected() ? 1 : 0; /* if identity is equal to node, fake is_connected */ if (endpoint->GetName() == IcingaApplication::GetInstance()->GetNodeName()) is_connected = 1; return is_connected; }
BOOST_FOREACH(const Endpoint::Ptr& endpoint, ConfigType::GetObjectsByType<Endpoint>()) { if (!endpoint->IsConnected()) continue; double ts = endpoint->GetRemoteLogPosition(); if (ts == 0) continue; Dictionary::Ptr lparams = new Dictionary(); lparams->Set("log_position", ts); Dictionary::Ptr lmessage = new Dictionary(); lmessage->Set("jsonrpc", "2.0"); lmessage->Set("method", "log::SetLogPosition"); lmessage->Set("params", lparams); BOOST_FOREACH(const JsonRpcConnection::Ptr& client, endpoint->GetClients()) client->SendMessage(lmessage); Log(LogNotice, "ApiListener") << "Setting log position for identity '" << endpoint->GetName() << "': " << Utility::FormatDateTime("%Y/%m/%d %H:%M:%S", ts); }
/** * Processes a new client connection. * * @param client The new client. */ void ApiListener::NewClientHandlerInternal(const Socket::Ptr& client, const String& hostname, ConnectionRole role) { CONTEXT("Handling new API client connection"); TlsStream::Ptr tlsStream; { ObjectLock olock(this); try { tlsStream = new TlsStream(client, hostname, role, m_SSLContext); } catch (const std::exception&) { Log(LogCritical, "ApiListener", "Cannot create TLS stream from client connection."); return; } } try { tlsStream->Handshake(); } catch (const std::exception& ex) { Log(LogCritical, "ApiListener", "Client TLS handshake failed"); return; } boost::shared_ptr<X509> cert = tlsStream->GetPeerCertificate(); String identity; Endpoint::Ptr endpoint; bool verify_ok = false; if (cert) { try { identity = GetCertificateCN(cert); } catch (const std::exception&) { Log(LogCritical, "ApiListener") << "Cannot get certificate common name from cert path: '" << GetCertPath() << "'."; return; } verify_ok = tlsStream->IsVerifyOK(); Log(LogInformation, "ApiListener") << "New client connection for identity '" << identity << "'" << (verify_ok ? "" : " (unauthenticated)"); if (verify_ok) endpoint = Endpoint::GetByName(identity); } else { Log(LogInformation, "ApiListener") << "New client connection (no client certificate)"; } bool need_sync = false; if (endpoint) need_sync = !endpoint->IsConnected(); ClientType ctype; if (role == RoleClient) { Dictionary::Ptr message = new Dictionary(); message->Set("jsonrpc", "2.0"); message->Set("method", "icinga::Hello"); message->Set("params", new Dictionary()); JsonRpc::SendMessage(tlsStream, message); ctype = ClientJsonRpc; } else { tlsStream->WaitForData(5); if (!tlsStream->IsDataAvailable()) { Log(LogWarning, "ApiListener", "No data received on new API connection."); return; } char firstByte; tlsStream->Peek(&firstByte, 1, false); if (firstByte >= '0' && firstByte <= '9') ctype = ClientJsonRpc; else ctype = ClientHttp; } if (ctype == ClientJsonRpc) { Log(LogNotice, "ApiListener", "New JSON-RPC client"); JsonRpcConnection::Ptr aclient = new JsonRpcConnection(identity, verify_ok, tlsStream, role); aclient->Start(); if (endpoint) { endpoint->AddClient(aclient); if (need_sync) { { ObjectLock olock(endpoint); endpoint->SetSyncing(true); } Log(LogInformation, "ApiListener") << "Sending updates for endpoint '" << endpoint->GetName() << "'."; /* sync zone file config */ SendConfigUpdate(aclient); /* sync runtime config */ SendRuntimeConfigObjects(aclient); Log(LogInformation, "ApiListener") << "Finished sending updates for endpoint '" << endpoint->GetName() << "'."; ReplayLog(aclient); } } else AddAnonymousClient(aclient); } else { Log(LogNotice, "ApiListener", "New HTTP client"); HttpServerConnection::Ptr aclient = new HttpServerConnection(identity, verify_ok, tlsStream); aclient->Start(); AddHttpClient(aclient); } }
void Checkable::ExecuteCheck() { CONTEXT("Executing check for object '" + GetName() + "'"); ASSERT(!OwnsLock()); UpdateNextCheck(); bool reachable = IsReachable(); { ObjectLock olock(this); /* don't run another check if there is one pending */ if (m_CheckRunning) return; m_CheckRunning = true; SetLastStateRaw(GetStateRaw()); SetLastStateType(GetLastStateType()); SetLastReachable(reachable); } /* keep track of scheduling info in case the check type doesn't provide its own information */ double scheduled_start = GetNextCheck(); double before_check = Utility::GetTime(); CheckResult::Ptr cr = new CheckResult(); cr->SetScheduleStart(scheduled_start); cr->SetExecutionStart(before_check); Endpoint::Ptr endpoint = GetCommandEndpoint(); bool local = !endpoint || endpoint == Endpoint::GetLocalEndpoint(); if (local) { GetCheckCommand()->Execute(this, cr, NULL, false); } else { Dictionary::Ptr macros = new Dictionary(); GetCheckCommand()->Execute(this, cr, macros, false); if (endpoint->IsConnected()) { /* perform check on remote endpoint */ Dictionary::Ptr message = new Dictionary(); message->Set("jsonrpc", "2.0"); message->Set("method", "event::ExecuteCommand"); Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(this); Dictionary::Ptr params = new Dictionary(); message->Set("params", params); params->Set("command_type", "check_command"); params->Set("command", GetCheckCommand()->GetName()); params->Set("host", host->GetName()); if (service) params->Set("service", service->GetShortName()); params->Set("macros", macros); ApiListener::Ptr listener = ApiListener::GetInstance(); if (listener) listener->SyncSendMessage(endpoint, message); } else if (Application::GetInstance()->GetStartTime() < Utility::GetTime() - 30) { /* fail to perform check on unconnected endpoint */ cr->SetState(ServiceUnknown); cr->SetOutput("Remote Icinga instance '" + endpoint->GetName() + "' " + "is not connected to '" + Endpoint::GetLocalEndpoint()->GetName() + "'"); ProcessCheckResult(cr); } { ObjectLock olock(this); m_CheckRunning = false; } } }