예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
	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);
	}
예제 #4
0
/**
 * 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);
	}
}
예제 #5
0
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;
		}
	}
}