Esempio n. 1
0
bool ConsoleHandler::AutocompleteScriptHelper(HttpRequest& request, HttpResponse& response,
    const String& command, const String& session, bool sandboxed)
{
	Log(LogInformation, "Console")
	    << "Auto-completing expression: " << command;

	ApiScriptFrame& lsf = l_ApiScriptFrames[session];
	lsf.Seen = Utility::GetTime();

	if (!lsf.Locals)
		lsf.Locals = new Dictionary();

	Array::Ptr results = new Array();
	Dictionary::Ptr resultInfo = new Dictionary();

	ScriptFrame frame;
	frame.Locals = lsf.Locals;
	frame.Self = lsf.Locals;
	frame.Sandboxed = sandboxed;

	resultInfo->Set("code", 200);
	resultInfo->Set("status", "Auto-completed successfully.");
	resultInfo->Set("suggestions", Array::FromVector(GetAutocompletionSuggestions(command, frame)));

	results->Add(resultInfo);

	Dictionary::Ptr result = new Dictionary();
	result->Set("results", results);

	response.SetStatus(200, "OK");
	HttpUtility::SendJsonBody(response, result);

	return true;
}
Esempio n. 2
0
void ApiEvents::CheckResultHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const MessageOrigin::Ptr& origin)
{
	std::vector<EventQueue::Ptr> queues = EventQueue::GetQueuesForType("CheckResult");

	if (queues.empty())
		return;

	Log(LogDebug, "ApiEvents", "Processing event type 'CheckResult'.");

	Dictionary::Ptr result = new Dictionary();
	result->Set("type", "CheckResult");
	result->Set("timestamp", Utility::GetTime());

	Host::Ptr host;
	Service::Ptr service;
	tie(host, service) = GetHostService(checkable);

	result->Set("host", host->GetName());
	if (service)
		result->Set("service", service->GetShortName());

	result->Set("check_result", Serialize(cr));

	BOOST_FOREACH(const EventQueue::Ptr& queue, queues) {
		queue->ProcessEvent(result);
	}
Esempio n. 3
0
Dictionary::Ptr ApiActions::AddComment(const ConfigObject::Ptr& object,
    const Dictionary::Ptr& params)
{
	Checkable::Ptr checkable = static_pointer_cast<Checkable>(object);

	if (!checkable)
		return ApiActions::CreateResult(404, "Cannot add comment for non-existent object");

	if (!params->Contains("author") || !params->Contains("comment"))
		return ApiActions::CreateResult(403, "Comments require author and comment.");

	String commentName = Comment::AddComment(checkable, CommentUser,
	    HttpUtility::GetLastParameter(params, "author"),
	    HttpUtility::GetLastParameter(params, "comment"), 0);

	Comment::Ptr comment = Comment::GetByName(commentName);

	Dictionary::Ptr additional = new Dictionary();
	additional->Set("name", commentName);
	additional->Set("legacy_id", comment->GetLegacyId());

	return ApiActions::CreateResult(200, "Successfully added comment '"
	    + commentName + "' for object '" + checkable->GetName()
	    + "'.", additional);
}
Esempio n. 4
0
	BOOST_FOREACH(const Endpoint::Ptr& endpoint, ConfigType::GetObjectsByType<Endpoint>()) {
		if (!endpoint->GetConnected())
			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);

		double maxTs = 0;

		BOOST_FOREACH(const JsonRpcConnection::Ptr& client, endpoint->GetClients()) {
			if (client->GetTimestamp() > maxTs)
				maxTs = client->GetTimestamp();
		}

		BOOST_FOREACH(const JsonRpcConnection::Ptr& client, endpoint->GetClients()) {
			if (client->GetTimestamp() != maxTs)
				client->Disconnect();
			else
				client->SendMessage(lmessage);
		}

		Log(LogNotice, "ApiListener")
		    << "Setting log position for identity '" << endpoint->GetName() << "': "
		    << Utility::FormatDateTime("%Y/%m/%d %H:%M:%S", ts);
	}
Esempio n. 5
0
void ElasticsearchWriter::Enqueue(const Checkable::Ptr& checkable, const String& type,
	const Dictionary::Ptr& fields, double ts)
{
	/* Atomically buffer the data point. */
	boost::mutex::scoped_lock lock(m_DataBufferMutex);

	/* Format the timestamps to dynamically select the date datatype inside the index. */
	fields->Set("@timestamp", FormatTimestamp(ts));
	fields->Set("timestamp", FormatTimestamp(ts));

	String eventType = m_EventPrefix + type;
	fields->Set("type", eventType);

	/* Every payload needs a line describing the index.
	 * We do it this way to avoid problems with a near full queue.
	 */
	String indexBody = "{\"index\": {} }\n";
	String fieldsBody = JsonEncode(fields);

	Log(LogDebug, "ElasticsearchWriter")
		<< "Checkable '" << checkable->GetName() << "' adds to metric list: '" << fieldsBody << "'.";

	m_DataBuffer.emplace_back(indexBody + fieldsBody);

	/* Flush if we've buffered too much to prevent excessive memory use. */
	if (static_cast<int>(m_DataBuffer.size()) >= GetFlushThreshold()) {
		Log(LogDebug, "ElasticsearchWriter")
			<< "Data buffer overflow writing " << m_DataBuffer.size() << " data points";
		Flush();
	}
}
Esempio n. 6
0
void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification,
    const User::Ptr& user, const CheckResult::Ptr& cr, int itype,
    const String& author, const String& comment, const Dictionary::Ptr& resolvedMacros,
    bool useResolvedMacros)
{
	NotificationCommand::Ptr commandObj = notification->GetCommand();

	NotificationType type = static_cast<NotificationType>(itype);

	Checkable::Ptr checkable = notification->GetCheckable();

	Dictionary::Ptr notificationExtra = new Dictionary();
	notificationExtra->Set("type", Notification::NotificationTypeToString(type));
	notificationExtra->Set("author", author);
	notificationExtra->Set("comment", comment);

	Host::Ptr host;
	Service::Ptr service;
	tie(host, service) = GetHostService(checkable);

	MacroProcessor::ResolverList resolvers;
	resolvers.push_back(std::make_pair("user", user));
	resolvers.push_back(std::make_pair("notification", notificationExtra));
	resolvers.push_back(std::make_pair("notification", notification));
	if (service)
		resolvers.push_back(std::make_pair("service", service));
	resolvers.push_back(std::make_pair("host", host));
	resolvers.push_back(std::make_pair("command", commandObj));
	resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance()));

	PluginUtility::ExecuteCommand(commandObj, checkable, cr, resolvers,
	    resolvedMacros, useResolvedMacros,
	    boost::bind(&PluginNotificationTask::ProcessFinishedHandler, checkable, _1, _2));
}
Esempio n. 7
0
void UserDbObject::OnConfigUpdate(void)
{
	Dictionary::Ptr fields = make_shared<Dictionary>();
	User::Ptr user = static_pointer_cast<User>(GetObject());

	/* contact addresses */
	Log(LogDebug, "db_ido", "contact addresses for '" + user->GetName() + "'");

	Dictionary::Ptr vars = user->GetVars();

	if (vars) { /* This is sparta. */
		for (int i = 1; i <= 6; i++) {
			String key = "address" + Convert::ToString(i);
			String val = vars->Get(key);

			if (val.IsEmpty())
				continue;

			fields->Set("contact_id", DbValue::FromObjectInsertID(user));
			fields->Set("address_number", i);
			fields->Set("address", val);
			fields->Set("instance_id", 0); /* DbConnection class fills in real ID */

			DbQuery query;
			query.Type = DbQueryInsert;
			query.Table = "contact_addresses";
			query.Fields = fields;
			OnQuery(query);
		}
	}
}
Esempio n. 8
0
String LogstashWriter::ComposeLogstashMessage(const Dictionary::Ptr& fields, const String& source, double ts)
{
        fields->Set("version", "1.1");
        fields->Set("host", source);
        fields->Set("timestamp", ts);

        return JsonEncode(fields) + "\n";
}
Esempio n. 9
0
String GelfWriter::ComposeGelfMessage(const Dictionary::Ptr& fields, const String& source)
{
    fields->Set("version", "1.1");
    fields->Set("host", source);
    fields->Set("timestamp", Utility::GetTime());

    return JsonEncode(fields);
}
Esempio n. 10
0
void JsonRpcConnection::MessageHandler(const String& jsonString)
{
	Dictionary::Ptr message = JsonRpc::DecodeMessage(jsonString);

	m_Seen = Utility::GetTime();

	if (m_HeartbeatTimeout != 0)
		m_NextHeartbeat = Utility::GetTime() + m_HeartbeatTimeout;

	if (m_Endpoint && message->Contains("ts")) {
		double ts = message->Get("ts");

		/* ignore old messages */
		if (ts < m_Endpoint->GetRemoteLogPosition())
			return;

		m_Endpoint->SetRemoteLogPosition(ts);
	}

	MessageOrigin::Ptr origin = new MessageOrigin();
	origin->FromClient = this;

	if (m_Endpoint) {
		if (m_Endpoint->GetZone() != Zone::GetLocalZone())
			origin->FromZone = m_Endpoint->GetZone();
		else
			origin->FromZone = Zone::GetByName(message->Get("originZone"));
	}

	String method = message->Get("method");

	Log(LogNotice, "JsonRpcConnection")
	    << "Received '" << method << "' message from '" << m_Identity << "'";

	Dictionary::Ptr resultMessage = new Dictionary();

	try {
		ApiFunction::Ptr afunc = ApiFunction::GetByName(method);

		if (!afunc)
			BOOST_THROW_EXCEPTION(std::invalid_argument("Function '" + method + "' does not exist."));

		resultMessage->Set("result", afunc->Invoke(origin, message->Get("params")));
	} catch (const std::exception& ex) {
		/* TODO: Add a user readable error message for the remote caller */
		resultMessage->Set("error", DiagnosticInformation(ex));
		std::ostringstream info;
		info << "Error while processing message for identity '" << m_Identity << "'";
		Log(LogWarning, "JsonRpcConnection")
		    << info.str() << "\n" << DiagnosticInformation(ex);
	}

	if (message->Contains("id")) {
		resultMessage->Set("jsonrpc", "2.0");
		resultMessage->Set("id", message->Get("id"));
		SendMessage(resultMessage);
	}
}
Esempio n. 11
0
void PerfdataWriter::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
{
	Dictionary::Ptr nodes = new Dictionary();

	for (const PerfdataWriter::Ptr& perfdatawriter : ConfigType::GetObjectsByType<PerfdataWriter>()) {
		nodes->Set(perfdatawriter->GetName(), 1); //add more stats
	}

	status->Set("perfdatawriter", nodes);
}
Esempio n. 12
0
void SyslogLogger::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
{
	Dictionary::Ptr nodes = new Dictionary();

	for (const SyslogLogger::Ptr& sysloglogger : ConfigType::GetObjectsByType<SyslogLogger>()) {
		nodes->Set(sysloglogger->GetName(), 1); //add more stats
	}

	status->Set("sysloglogger", nodes);
}
void ExternalCommandListener::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
{
	Dictionary::Ptr nodes = new Dictionary();

	for (const ExternalCommandListener::Ptr& externalcommandlistener : ConfigType::GetObjectsByType<ExternalCommandListener>()) {
		nodes->Set(externalcommandlistener->GetName(), 1); //add more stats
	}

	status->Set("externalcommandlistener", nodes);
}
Esempio n. 14
0
void PerfdataWriter::InternalSerialize(const Dictionary::Ptr& bag, int attributeTypes) const
{
	DynamicObject::InternalSerialize(bag, attributeTypes);

	if (attributeTypes & Attribute_Config) {
		bag->Set("perfdata_path", m_PerfdataPath);
		bag->Set("format_template", m_FormatTemplate);
		bag->Set("rotation_interval", m_RotationInterval);
	}
}
void CheckResultReader::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
{
	Dictionary::Ptr nodes = new Dictionary();

	for (const CheckResultReader::Ptr& checkresultreader : ConfigType::GetObjectsByType<CheckResultReader>()) {
		nodes->Set(checkresultreader->GetName(), 1); //add more stats
	}

	status->Set("checkresultreader", nodes);
}
Esempio n. 16
0
void NotificationComponent::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
{
	Dictionary::Ptr nodes = new Dictionary();

	for (const NotificationComponent::Ptr& notification_component : ConfigType::GetObjectsByType<NotificationComponent>()) {
		nodes->Set(notification_component->GetName(), 1); //add more stats
	}

	status->Set("notificationcomponent", nodes);
}
Esempio n. 17
0
void InfluxdbWriter::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&)
{
	Dictionary::Ptr nodes = new Dictionary();

	for (const InfluxdbWriter::Ptr& influxdbwriter : ConfigType::GetObjectsByType<InfluxdbWriter>()) {
		nodes->Set(influxdbwriter->GetName(), 1); //add more stats
	}

	status->Set("influxdbwriter", nodes);
}
Esempio n. 18
0
Dictionary::Ptr EndpointDbObject::GetConfigFields(void) const
{
    Dictionary::Ptr fields = new Dictionary();
    Endpoint::Ptr endpoint = static_pointer_cast<Endpoint>(GetObject());

    fields->Set("identity", endpoint->GetName());
    fields->Set("node", IcingaApplication::GetInstance()->GetNodeName());

    return fields;
}
Esempio n. 19
0
void ConfigObject::DumpObjects(const String& filename, int attributeTypes)
{
	Log(LogInformation, "ConfigObject")
	    << "Dumping program state to file '" << filename << "'";

	std::fstream fp;
	String tempFilename = Utility::CreateTempFile(filename + ".XXXXXX", 0600, fp);
	fp.exceptions(std::ofstream::failbit | std::ofstream::badbit);

	if (!fp)
		BOOST_THROW_EXCEPTION(std::runtime_error("Could not open '" + tempFilename + "' file"));

	StdioStream::Ptr sfp = new StdioStream(&fp, false);

	for (const Type::Ptr& type : Type::GetAllTypes()) {
		ConfigType *dtype = dynamic_cast<ConfigType *>(type.get());

		if (!dtype)
			continue;

		for (const ConfigObject::Ptr& object : dtype->GetObjects()) {
			Dictionary::Ptr persistentObject = new Dictionary();

			persistentObject->Set("type", type->GetName());
			persistentObject->Set("name", object->GetName());

			Dictionary::Ptr update = Serialize(object, attributeTypes);

			if (!update)
				continue;

			persistentObject->Set("update", update);

			String json = JsonEncode(persistentObject);

			NetString::WriteStringToStream(sfp, json);
		}
	}

	sfp->Close();

	fp.close();

#ifdef _WIN32
	_unlink(filename.CStr());
#endif /* _WIN32 */

	if (rename(tempFilename.CStr(), filename.CStr()) < 0) {
		BOOST_THROW_EXCEPTION(posix_error()
		    << boost::errinfo_api_function("rename")
		    << boost::errinfo_errno(errno)
		    << boost::errinfo_file_name(tempFilename));
	}
}
Esempio n. 20
0
Dictionary::Ptr LegacyTimePeriod::ProcessTimeRange(const String& timestamp, tm *reference)
{
	tm begin, end;

	ProcessTimeRangeRaw(timestamp, reference, &begin, &end);

	Dictionary::Ptr segment = new Dictionary();
	segment->Set("begin", (long)mktime(&begin));
	segment->Set("end", (long)mktime(&end));
	return segment;
}
Esempio n. 21
0
		BOOST_FOREACH(const Object::Ptr& pobj, DependencyGraph::GetParents((obj))) {
			ConfigObject::Ptr configObj = dynamic_pointer_cast<ConfigObject>(pobj);

			if (!configObj)
				continue;

			Dictionary::Ptr refInfo = new Dictionary();
			refInfo->Set("type", configObj->GetType()->GetName());
			refInfo->Set("name", configObj->GetName());
			used_by->Add(refInfo);
		}
Esempio n. 22
0
void TimePeriod::AddSegment(double begin, double end)
{
	ASSERT(OwnsLock());

	Log(LogDebug, "TimePeriod")
	    << "Adding segment '" << Utility::FormatDateTime("%c", begin) << "' <-> '"
	    << Utility::FormatDateTime("%c", end) << "' to TimePeriod '" << GetName() << "'";

	if (GetValidBegin().IsEmpty() || begin < GetValidBegin())
		SetValidBegin(begin);

	if (GetValidEnd().IsEmpty() || end > GetValidEnd())
		SetValidEnd(end);

	Array::Ptr segments = GetSegments();

	if (segments) {
		/* Try to merge the new segment into an existing segment. */
		ObjectLock dlock(segments);
		for (const Dictionary::Ptr& segment : segments) {
			if (segment->Get("begin") <= begin && segment->Get("end") >= end)
				return; /* New segment is fully contained in this segment. */

			if (segment->Get("begin") >= begin && segment->Get("end") <= end) {
				segment->Set("begin", begin);
				segment->Set("end", end); /* Extend an existing segment to both sides */
				return;
			}

			if (segment->Get("end") >= begin && segment->Get("end") <= end) {
				segment->Set("end", end); /* Extend an existing segment to right. */
				return;
			}

			if (segment->Get("begin") >= begin && segment->Get("begin") <= end) {
				segment->Set("begin", begin); /* Extend an existing segment to left. */
				return;
			}

		}
	}

	/* Create new segment if we weren't able to merge this into an existing segment. */
	Dictionary::Ptr segment = new Dictionary();
	segment->Set("begin", begin);
	segment->Set("end", end);

	if (!segments) {
		segments = new Array();
		SetSegments(segments);
	}

	segments->Add(segment);
}
Esempio n. 23
0
void HttpUtility::SendJsonError(HttpResponse& response, const int code,
    const String& info, const String& diagnosticInformation)
{
	Dictionary::Ptr result = new Dictionary();
	response.SetStatus(code, HttpUtility::GetErrorNameByCode(code));
	result->Set("error", code);
	if (!info.IsEmpty())
		result->Set("status", info);
	if (!diagnosticInformation.IsEmpty())
		result->Set("diagnostic information", diagnosticInformation);
	HttpUtility::SendJsonBody(response, result);
}
Esempio n. 24
0
Dictionary::Ptr ApiActions::CreateResult(int code, const String& status,
    const Dictionary::Ptr& additional)
{
	Dictionary::Ptr result = new Dictionary();
	result->Set("code", code);
	result->Set("status", status);

	if (additional)
		additional->CopyTo(result);

	return result;
}
Esempio n. 25
0
Object::Ptr ConfigObject::GetPrototype(void)
{
	static Dictionary::Ptr prototype;

	if (!prototype) {
		prototype = new Dictionary();
		prototype->Set("modify_attribute", new Function("ConfigObject#modify_attribute", WrapFunction(ConfigObjectModifyAttribute), false));
		prototype->Set("restore_attribute", new Function("ConfigObject#restore_attribute", WrapFunction(ConfigObjectRestoreAttribute), false));
	}

	return prototype;
}
Esempio n. 26
0
Dictionary::Ptr UserDbObject::GetStatusFields(void) const
{
	Dictionary::Ptr fields = new Dictionary();
	User::Ptr user = static_pointer_cast<User>(GetObject());

	fields->Set("host_notifications_enabled", user->GetEnableNotifications());
	fields->Set("service_notifications_enabled", user->GetEnableNotifications());
	fields->Set("last_host_notification", DbValue::FromTimestamp(user->GetLastNotification()));
	fields->Set("last_service_notification", DbValue::FromTimestamp(user->GetLastNotification()));

	return fields;
}
Esempio n. 27
0
Dictionary::Ptr ServiceGroupDbObject::GetConfigFields(void) const
{
	Dictionary::Ptr fields = new Dictionary();
	ServiceGroup::Ptr group = static_pointer_cast<ServiceGroup>(GetObject());

	fields->Set("alias", group->GetDisplayName());
	fields->Set("notes", group->GetNotes());
	fields->Set("notes_url", group->GetNotesUrl());
	fields->Set("action_url", group->GetActionUrl());

	return fields;
}
Esempio n. 28
0
Dictionary::Ptr HostGroupDbObject::GetConfigFields(void) const
{
	Dictionary::Ptr fields = make_shared<Dictionary>();
	HostGroup::Ptr group = static_pointer_cast<HostGroup>(GetObject());

	fields->Set("alias", group->GetDisplayName());
	fields->Set("notes", group->GetNotes());
	fields->Set("notes_url", group->GetNotesUrl());
	fields->Set("action_url", group->GetActionUrl());

	return fields;
}
Esempio n. 29
0
bool ObjectQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response)
{
	if (request.RequestUrl->GetPath().size() < 3 || request.RequestUrl->GetPath().size() > 4)
		return false;

	if (request.RequestMethod != "GET")
		return false;

	Type::Ptr type = FilterUtility::TypeFromPluralName(request.RequestUrl->GetPath()[2]);

	if (!type) {
		HttpUtility::SendJsonError(response, 400, "Invalid type specified.");
		return true;
	}

	QueryDescription qd;
	qd.Types.insert(type->GetName());
	qd.Permission = "objects/query/" + type->GetName();

	std::vector<String> joinAttrs;
	joinAttrs.push_back("");

	for (int fid = 0; fid < type->GetFieldCount(); fid++) {
		Field field = type->GetFieldInfo(fid);

		if (field.Attributes & FANavigation)
			joinAttrs.push_back(field.Name);
	}

	Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request);

	params->Set("type", type->GetName());

	if (request.RequestUrl->GetPath().size() >= 4) {
		String attr = type->GetName();
		boost::algorithm::to_lower(attr);
		params->Set(attr, request.RequestUrl->GetPath()[3]);
	}

	std::vector<Value> objs = FilterUtility::GetFilterTargets(qd, params, user);

	Array::Ptr results = new Array();

	std::set<String> attrs;
	Array::Ptr uattrs = params->Get("attrs");

	if (uattrs) {
		ObjectLock olock(uattrs);
		BOOST_FOREACH(const String& uattr, uattrs) {
			attrs.insert(uattr);
		}
	}
Esempio n. 30
0
Dictionary::Ptr EndpointDbObject::GetStatusFields(void) const
{
	Dictionary::Ptr fields = make_shared<Dictionary>();
	Endpoint::Ptr endpoint = static_pointer_cast<Endpoint>(GetObject());

	Log(LogDebug, "EndpointDbObject", "update status for endpoint '" + endpoint->GetName() + "'");

	fields->Set("identity", endpoint->GetName());
	fields->Set("node", IcingaApplication::GetInstance()->GetNodeName());
	fields->Set("is_connected", EndpointIsConnected(endpoint));

	return fields;
}