Ejemplo n.º 1
0
Value ServicesTable::CustomVariablesAccessor(const Value& row)
{
	Service::Ptr service = static_cast<Service::Ptr>(row);

	if (!service)
		return Empty;

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

	ArrayData result;

	if (vars) {
		ObjectLock olock(vars);
		for (const Dictionary::Pair& kv : vars) {
			Value val;

			if (kv.second.IsObjectType<Array>() || kv.second.IsObjectType<Dictionary>())
				val = JsonEncode(kv.second);
			else
				val = kv.second;

			result.push_back(new Array({
				kv.first,
				val
			}));
		}
	}

	return new Array(std::move(result));
}
Ejemplo n.º 2
0
void ElasticsearchWriter::NotificationSentToAllUsersHandlerInternal(const Notification::Ptr& notification,
	const Checkable::Ptr& checkable, const std::set<User::Ptr>& users, NotificationType type,
	const CheckResult::Ptr& cr, const String& author, const String& text)
{
	AssertOnWorkQueue();

	CONTEXT("Elasticwriter processing notification to all users '" + checkable->GetName() + "'");

	Log(LogDebug, "ElasticsearchWriter")
		<< "Processing notification for '" << checkable->GetName() << "'";

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

	String notificationTypeString = Notification::NotificationTypeToString(type);

	Dictionary::Ptr fields = new Dictionary();

	if (service) {
		fields->Set("service", service->GetShortName());
		fields->Set("state", service->GetState());
		fields->Set("last_state", service->GetLastState());
		fields->Set("last_hard_state", service->GetLastHardState());
	} else {
		fields->Set("state", host->GetState());
		fields->Set("last_state", host->GetLastState());
		fields->Set("last_hard_state", host->GetLastHardState());
	}

	fields->Set("host", host->GetName());

	ArrayData userNames;

	for (const User::Ptr& user : users) {
		userNames.push_back(user->GetName());
	}

	fields->Set("users", new Array(std::move(userNames)));
	fields->Set("notification_type", notificationTypeString);
	fields->Set("author", author);
	fields->Set("text", text);

	CheckCommand::Ptr commandObj = checkable->GetCheckCommand();

	if (commandObj)
		fields->Set("check_command", commandObj->GetName());

	double ts = Utility::GetTime();

	if (cr) {
		AddCheckResult(fields, checkable, cr);
		ts = cr->GetExecutionEnd();
	}

	Enqueue(checkable, "notification", fields, ts);
}
Ejemplo n.º 3
0
Value ServicesTable::ContactsAccessor(const Value& row)
{
	Service::Ptr service = static_cast<Service::Ptr>(row);

	if (!service)
		return Empty;

	ArrayData result;

	for (const User::Ptr& user : CompatUtility::GetCheckableNotificationUsers(service)) {
		result.push_back(user->GetName());
	}

	return new Array(std::move(result));
}
Ejemplo n.º 4
0
Value ServiceGroupsTable::MembersAccessor(const Value& row)
{
	ServiceGroup::Ptr sg = static_cast<ServiceGroup::Ptr>(row);

	if (!sg)
		return Empty;

	ArrayData result;

	for (const Service::Ptr& service : sg->GetMembers()) {
		result.push_back(new Array({
			service->GetHost()->GetName(),
			service->GetShortName()
		}));
	}

	return new Array(std::move(result));
}
Ejemplo n.º 5
0
Value ServicesTable::CommentsAccessor(const Value& row)
{
	Service::Ptr service = static_cast<Service::Ptr>(row);

	if (!service)
		return Empty;

	ArrayData result;

	for (const Comment::Ptr& comment : service->GetComments()) {
		if (comment->IsExpired())
			continue;

		result.push_back(comment->GetLegacyId());
	}

	return new Array(std::move(result));
}
Ejemplo n.º 6
0
void ClusterEvents::NotificationSentToAllUsersHandler(const Notification::Ptr& notification, const Checkable::Ptr& checkable, const std::set<User::Ptr>& users,
	NotificationType notificationType, const CheckResult::Ptr& cr, const String& author, const String& commentText, const MessageOrigin::Ptr& origin)
{
	ApiListener::Ptr listener = ApiListener::GetInstance();

	if (!listener)
		return;

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

	Dictionary::Ptr params = new Dictionary();
	params->Set("host", host->GetName());
	if (service)
		params->Set("service", service->GetShortName());
	params->Set("notification", notification->GetName());

	ArrayData ausers;
	for (const User::Ptr& user : users) {
		ausers.push_back(user->GetName());
	}
	params->Set("users", new Array(std::move(ausers)));

	params->Set("type", notificationType);
	params->Set("cr", Serialize(cr));
	params->Set("author", author);
	params->Set("text", commentText);

	params->Set("last_notification", notification->GetLastNotification());
	params->Set("next_notification", notification->GetNextNotification());
	params->Set("notification_number", notification->GetNotificationNumber());
	params->Set("last_problem_notification", notification->GetLastProblemNotification());
	params->Set("no_more_notifications", notification->GetNoMoreNotifications());

	Dictionary::Ptr message = new Dictionary();
	message->Set("jsonrpc", "2.0");
	message->Set("method", "event::NotificationSentToAllUsers");
	message->Set("params", params);

	listener->RelayMessage(origin, nullptr, message, true);
}
Ejemplo n.º 7
0
Value ServicesTable::CustomVariableNamesAccessor(const Value& row)
{
	Service::Ptr service = static_cast<Service::Ptr>(row);

	if (!service)
		return Empty;

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

	ArrayData result;

	if (vars) {
		ObjectLock olock(vars);
		for (const Dictionary::Pair& kv : vars) {
			result.push_back(kv.first);
		}
	}

	return new Array(std::move(result));
}
Ejemplo n.º 8
0
Value CommandsTable::CustomVariableValuesAccessor(const Value& row)
{
	Command::Ptr command = static_cast<Command::Ptr>(row);

	if (!command)
		return Empty;

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

	ArrayData keys;

	if (vars) {
		ObjectLock xlock(vars);
		for (const auto& kv : vars) {
			keys.push_back(kv.second);
		}
	}

	return new Array(std::move(keys));
}
Ejemplo n.º 9
0
Value ServicesTable::DowntimesWithInfoAccessor(const Value& row)
{
	Service::Ptr service = static_cast<Service::Ptr>(row);

	if (!service)
		return Empty;

	ArrayData result;

	for (const Downtime::Ptr& downtime : service->GetDowntimes()) {
		if (downtime->IsExpired())
			continue;

		result.push_back(new Array({
			downtime->GetLegacyId(),
			downtime->GetAuthor(),
			downtime->GetComment()
		}));
	}

	return new Array(std::move(result));
}
Ejemplo n.º 10
0
Value CommandsTable::CustomVariablesAccessor(const Value& row)
{
	Command::Ptr command = static_cast<Command::Ptr>(row);

	if (!command)
		return Empty;

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

	ArrayData result;

	if (vars) {
		ObjectLock xlock(vars);
		for (const auto& kv : vars) {
			result.push_back(new Array({
				kv.first,
				kv.second
			}));
		}
	}

	return new Array(std::move(result));
}
Ejemplo n.º 11
0
Value ServicesTable::CommentsWithExtraInfoAccessor(const Value& row)
{
	Service::Ptr service = static_cast<Service::Ptr>(row);

	if (!service)
		return Empty;

	ArrayData result;

	for (const Comment::Ptr& comment : service->GetComments()) {
		if (comment->IsExpired())
			continue;

		result.push_back(new Array({
			comment->GetLegacyId(),
			comment->GetAuthor(),
			comment->GetText(),
			comment->GetEntryType(),
			static_cast<int>(comment->GetEntryTime())
		}));
	}

	return new Array(std::move(result));
}
Ejemplo n.º 12
0
bool ObjectQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params)
{
	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, params, 400, "Invalid type specified.");
		return true;
	}

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

	Array::Ptr uattrs, ujoins, umetas;

	try {
		uattrs = params->Get("attrs");
	} catch (const std::exception&) {
		HttpUtility::SendJsonError(response, params, 400,
			"Invalid type for 'attrs' attribute specified. Array type is required.");
		return true;
	}

	try {
		ujoins = params->Get("joins");
	} catch (const std::exception&) {
		HttpUtility::SendJsonError(response, params, 400,
			"Invalid type for 'joins' attribute specified. Array type is required.");
		return true;
	}

	try {
		umetas = params->Get("meta");
	} catch (const std::exception&) {
		HttpUtility::SendJsonError(response, params, 400,
			"Invalid type for 'meta' attribute specified. Array type is required.");
		return true;
	}

	bool allJoins = HttpUtility::GetLastParameter(params, "all_joins");

	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;

	try {
		objs = FilterUtility::GetFilterTargets(qd, params, user);
	} catch (const std::exception& ex) {
		HttpUtility::SendJsonError(response, params, 404,
			"No objects found.",
			DiagnosticInformation(ex));
		return true;
	}

	ArrayData results;
	results.reserve(objs.size());

	std::set<String> joinAttrs;
	std::set<String> userJoinAttrs;

	if (ujoins) {
		ObjectLock olock(ujoins);
		for (const String& ujoin : ujoins) {
			userJoinAttrs.insert(ujoin.SubStr(0, ujoin.FindFirstOf(".")));
		}
	}

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

		if (!(field.Attributes & FANavigation))
			continue;

		if (!allJoins && userJoinAttrs.find(field.NavigationName) == userJoinAttrs.end())
			continue;

		joinAttrs.insert(field.Name);
	}

	for (const ConfigObject::Ptr& obj : objs) {
		DictionaryData result1{
			{ "name", obj->GetName() },
			{ "type", obj->GetReflectionType()->GetName() }
		};

		DictionaryData metaAttrs;

		if (umetas) {
			ObjectLock olock(umetas);
			for (const String& meta : umetas) {
				if (meta == "used_by") {
					Array::Ptr used_by = new Array();
					metaAttrs.emplace_back("used_by", used_by);

					for (const Object::Ptr& pobj : DependencyGraph::GetParents((obj)))
					{
						ConfigObject::Ptr configObj = dynamic_pointer_cast<ConfigObject>(pobj);

						if (!configObj)
							continue;

						used_by->Add(new Dictionary({
							{ "type", configObj->GetReflectionType()->GetName() },
							{ "name", configObj->GetName() }
						}));
					}
				} else if (meta == "location") {
					metaAttrs.emplace_back("location", obj->GetSourceLocation());
				} else {
					HttpUtility::SendJsonError(response, params, 400, "Invalid field specified for meta: " + meta);
					return true;
				}
			}
		}

		result1.emplace_back("meta", new Dictionary(std::move(metaAttrs)));

		try {
			result1.emplace_back("attrs", SerializeObjectAttrs(obj, String(), uattrs, false, false));
		} catch (const ScriptError& ex) {
			HttpUtility::SendJsonError(response, params, 400, ex.what());
			return true;
		}

		DictionaryData joins;

		for (const String& joinAttr : joinAttrs) {
			Object::Ptr joinedObj;
			int fid = type->GetFieldId(joinAttr);

			if (fid < 0) {
				HttpUtility::SendJsonError(response, params, 400, "Invalid field specified for join: " + joinAttr);
				return true;
			}

			Field field = type->GetFieldInfo(fid);

			if (!(field.Attributes & FANavigation)) {
				HttpUtility::SendJsonError(response, params, 400, "Not a joinable field: " + joinAttr);
				return true;
			}

			joinedObj = obj->NavigateField(fid);

			if (!joinedObj)
				continue;

			String prefix = field.NavigationName;

			try {
				joins.emplace_back(prefix, SerializeObjectAttrs(joinedObj, prefix, ujoins, true, allJoins));
			} catch (const ScriptError& ex) {
				HttpUtility::SendJsonError(response, params, 400, ex.what());
				return true;
			}
		}

		result1.emplace_back("joins", new Dictionary(std::move(joins)));

		results.push_back(new Dictionary(std::move(result1)));
	}

	Dictionary::Ptr result = new Dictionary({
		{ "results", new Array(std::move(results)) }
	});

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

	return true;
}
Ejemplo n.º 13
0
Value ClusterEvents::CheckResultAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
{
	Endpoint::Ptr endpoint = origin->FromClient->GetEndpoint();

	if (!endpoint) {
		Log(LogNotice, "ClusterEvents")
			<< "Discarding 'check result' message from '" << origin->FromClient->GetIdentity() << "': Invalid endpoint origin (client not allowed).";
		return Empty;
	}

	CheckResult::Ptr cr;
	Array::Ptr vperf;

	if (params->Contains("cr")) {
		cr = new CheckResult();
		Dictionary::Ptr vcr = params->Get("cr");

		if (vcr && vcr->Contains("performance_data")) {
			vperf = vcr->Get("performance_data");

			if (vperf)
				vcr->Remove("performance_data");

			Deserialize(cr, vcr, true);
		}
	}

	if (!cr)
		return Empty;

	ArrayData rperf;

	if (vperf) {
		ObjectLock olock(vperf);
		for (const Value& vp : vperf) {
			Value p;

			if (vp.IsObjectType<Dictionary>()) {
				PerfdataValue::Ptr val = new PerfdataValue();
				Deserialize(val, vp, true);
				rperf.push_back(val);
			} else
				rperf.push_back(vp);
		}
	}

	cr->SetPerformanceData(new Array(std::move(rperf)));

	Host::Ptr host = Host::GetByName(params->Get("host"));

	if (!host)
		return Empty;

	Checkable::Ptr checkable;

	if (params->Contains("service"))
		checkable = host->GetServiceByShortName(params->Get("service"));
	else
		checkable = host;

	if (!checkable)
		return Empty;

	if (origin->FromZone && !origin->FromZone->CanAccessObject(checkable) && endpoint != checkable->GetCommandEndpoint()) {
		Log(LogNotice, "ClusterEvents")
			<< "Discarding 'check result' message for checkable '" << checkable->GetName()
			<< "' from '" << origin->FromClient->GetIdentity() << "': Unauthorized access.";
		return Empty;
	}

	if (!checkable->IsPaused() && Zone::GetLocalZone() == checkable->GetZone() && endpoint == checkable->GetCommandEndpoint())
		checkable->ProcessCheckResult(cr);
	else
		checkable->ProcessCheckResult(cr, origin);

	return Empty;
}
Ejemplo n.º 14
0
Value ClusterEvents::NotificationSentToAllUsersAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params)
{
	Endpoint::Ptr endpoint = origin->FromClient->GetEndpoint();

	if (!endpoint) {
		Log(LogNotice, "ClusterEvents")
			<< "Discarding 'sent notification to all users' message from '" << origin->FromClient->GetIdentity() << "': Invalid endpoint origin (client not allowed).";
		return Empty;
	}

	Host::Ptr host = Host::GetByName(params->Get("host"));

	if (!host)
		return Empty;

	Checkable::Ptr checkable;

	if (params->Contains("service"))
		checkable = host->GetServiceByShortName(params->Get("service"));
	else
		checkable = host;

	if (!checkable)
		return Empty;

	if (origin->FromZone && origin->FromZone != Zone::GetLocalZone()) {
		Log(LogNotice, "ClusterEvents")
			<< "Discarding 'sent notification to all users' message for checkable '" << checkable->GetName()
			<< "' from '" << origin->FromClient->GetIdentity() << "': Unauthorized access.";
		return Empty;
	}

	CheckResult::Ptr cr;
	Array::Ptr vperf;

	if (params->Contains("cr")) {
		cr = new CheckResult();
		Dictionary::Ptr vcr = params->Get("cr");

		if (vcr && vcr->Contains("performance_data")) {
			vperf = vcr->Get("performance_data");

			if (vperf)
				vcr->Remove("performance_data");

			Deserialize(cr, vcr, true);
		}
	}

	NotificationType type = static_cast<NotificationType>(static_cast<int>(params->Get("type")));
	String author = params->Get("author");
	String text = params->Get("text");

	Notification::Ptr notification = Notification::GetByName(params->Get("notification"));

	if (!notification)
		return Empty;

	Array::Ptr ausers = params->Get("users");

	if (!ausers)
		return Empty;

	std::set<User::Ptr> users;

	{
		ObjectLock olock(ausers);
		for (const String& auser : ausers) {
			User::Ptr user = User::GetByName(auser);

			if (!user)
				continue;

			users.insert(user);
		}
	}

	notification->SetLastNotification(params->Get("last_notification"));
	notification->SetNextNotification(params->Get("next_notification"));
	notification->SetNotificationNumber(params->Get("notification_number"));
	notification->SetLastProblemNotification(params->Get("last_problem_notification"));
	notification->SetNoMoreNotifications(params->Get("no_more_notifications"));

	ArrayData notifiedProblemUsers;
	for (const User::Ptr& user : users) {
		notifiedProblemUsers.push_back(user->GetName());
	}

	notification->SetNotifiedProblemUsers(new Array(std::move(notifiedProblemUsers)));

	Checkable::OnNotificationSentToAllUsers(notification, checkable, users, type, cr, author, text, origin);

	return Empty;
}