mirror of https://github.com/Icinga/icinga2.git
parent
8caac68f76
commit
1a6b41787a
|
@ -107,6 +107,11 @@ void Object::NotifyField(int id, const Value& cookie)
|
||||||
BOOST_THROW_EXCEPTION(std::runtime_error("Invalid field ID."));
|
BOOST_THROW_EXCEPTION(std::runtime_error("Invalid field ID."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object::Ptr Object::NavigateField(int id) const
|
||||||
|
{
|
||||||
|
BOOST_THROW_EXCEPTION(std::runtime_error("Invalid field ID."));
|
||||||
|
}
|
||||||
|
|
||||||
Object::Ptr Object::Clone(void) const
|
Object::Ptr Object::Clone(void) const
|
||||||
{
|
{
|
||||||
BOOST_THROW_EXCEPTION(std::runtime_error("Object cannot be cloned."));
|
BOOST_THROW_EXCEPTION(std::runtime_error("Object cannot be cloned."));
|
||||||
|
|
|
@ -109,6 +109,7 @@ public:
|
||||||
virtual Value GetField(int id) const;
|
virtual Value GetField(int id) const;
|
||||||
virtual void ValidateField(int id, const Value& value, const ValidationUtils& utils);
|
virtual void ValidateField(int id, const Value& value, const ValidationUtils& utils);
|
||||||
virtual void NotifyField(int id, const Value& cookie = Empty);
|
virtual void NotifyField(int id, const Value& cookie = Empty);
|
||||||
|
virtual Object::Ptr NavigateField(int id) const;
|
||||||
|
|
||||||
#ifdef I2_DEBUG
|
#ifdef I2_DEBUG
|
||||||
bool OwnsLock(void) const;
|
bool OwnsLock(void) const;
|
||||||
|
|
|
@ -169,11 +169,11 @@ Field TypeType::GetFieldInfo(int id) const
|
||||||
return GetBaseType()->GetFieldInfo(id);
|
return GetBaseType()->GetFieldInfo(id);
|
||||||
|
|
||||||
if (id == 0)
|
if (id == 0)
|
||||||
return Field(0, "String", "name", NULL, 0, 0);
|
return Field(0, "String", "name", "", NULL, 0, 0);
|
||||||
else if (id == 1)
|
else if (id == 1)
|
||||||
return Field(1, "Object", "prototype", NULL, 0, 0);
|
return Field(1, "Object", "prototype", "", NULL, 0, 0);
|
||||||
else if (id == 2)
|
else if (id == 2)
|
||||||
return Field(2, "Type", "base", NULL, 0, 0);
|
return Field(2, "Type", "base", "", NULL, 0, 0);
|
||||||
|
|
||||||
throw std::runtime_error("Invalid field ID.");
|
throw std::runtime_error("Invalid field ID.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,8 @@ enum FieldAttribute
|
||||||
FAConfig = 2,
|
FAConfig = 2,
|
||||||
FAState = 4,
|
FAState = 4,
|
||||||
FAInternal = 64,
|
FAInternal = 64,
|
||||||
FARequired = 512
|
FARequired = 512,
|
||||||
|
FANavigation = 1024
|
||||||
};
|
};
|
||||||
|
|
||||||
class Type;
|
class Type;
|
||||||
|
@ -47,12 +48,13 @@ struct Field
|
||||||
int ID;
|
int ID;
|
||||||
const char *TypeName;
|
const char *TypeName;
|
||||||
const char *Name;
|
const char *Name;
|
||||||
|
const char *NavigationName;
|
||||||
const char *RefTypeName;
|
const char *RefTypeName;
|
||||||
int Attributes;
|
int Attributes;
|
||||||
int ArrayRank;
|
int ArrayRank;
|
||||||
|
|
||||||
Field(int id, const char *type, const char *name, const char *reftype, int attributes, int arrayRank)
|
Field(int id, const char *type, const char *name, const char *navigationName, const char *reftype, int attributes, int arrayRank)
|
||||||
: ID(id), TypeName(type), Name(name), RefTypeName(reftype), Attributes(attributes), ArrayRank(arrayRank)
|
: ID(id), TypeName(type), Name(name), NavigationName(navigationName), RefTypeName(reftype), Attributes(attributes), ArrayRank(arrayRank)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ boost::signals2::signal<void (const Checkable::Ptr&, NotificationType, const Che
|
||||||
|
|
||||||
CheckCommand::Ptr Checkable::GetCheckCommand(void) const
|
CheckCommand::Ptr Checkable::GetCheckCommand(void) const
|
||||||
{
|
{
|
||||||
return CheckCommand::GetByName(GetCheckCommandRaw());
|
return dynamic_pointer_cast<CheckCommand>(NavigateCheckCommandRaw());
|
||||||
}
|
}
|
||||||
|
|
||||||
TimePeriod::Ptr Checkable::GetCheckPeriod(void) const
|
TimePeriod::Ptr Checkable::GetCheckPeriod(void) const
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "icinga/icingaapplication.hpp"
|
#include "icinga/icingaapplication.hpp"
|
||||||
#include "icinga/customvarobject.hpp"
|
#include "icinga/customvarobject.hpp"
|
||||||
#include "base/array.hpp"
|
#include "base/array.hpp"
|
||||||
|
#impl_include "icinga/checkcommand.hpp"
|
||||||
|
#impl_include "icinga/eventcommand.hpp"
|
||||||
|
|
||||||
library icinga;
|
library icinga;
|
||||||
|
|
||||||
|
@ -42,18 +44,30 @@ enum AcknowledgementType
|
||||||
|
|
||||||
abstract class Checkable : CustomVarObject
|
abstract class Checkable : CustomVarObject
|
||||||
{
|
{
|
||||||
[config, required] name(CheckCommand) check_command (CheckCommandRaw);
|
[config, required, navigation] name(CheckCommand) check_command (CheckCommandRaw) {
|
||||||
|
navigate {{{
|
||||||
|
return CheckCommand::GetByName(GetCheckCommandRaw());
|
||||||
|
}}}
|
||||||
|
};
|
||||||
[config] int max_check_attempts {
|
[config] int max_check_attempts {
|
||||||
default {{{ return 3; }}}
|
default {{{ return 3; }}}
|
||||||
};
|
};
|
||||||
[config] name(TimePeriod) check_period (CheckPeriodRaw);
|
[config, navigation] name(TimePeriod) check_period (CheckPeriodRaw) {
|
||||||
|
navigate {{{
|
||||||
|
return TimePeriod::GetByName(GetCheckPeriodRaw());
|
||||||
|
}}}
|
||||||
|
};
|
||||||
[config] double check_interval {
|
[config] double check_interval {
|
||||||
default {{{ return 5 * 60; }}}
|
default {{{ return 5 * 60; }}}
|
||||||
};
|
};
|
||||||
[config] double retry_interval {
|
[config] double retry_interval {
|
||||||
default {{{ return 60; }}}
|
default {{{ return 60; }}}
|
||||||
};
|
};
|
||||||
[config] name(EventCommand) event_command (EventCommandRaw);
|
[config, navigation] name(EventCommand) event_command (EventCommandRaw) {
|
||||||
|
navigate {{{
|
||||||
|
return EventCommand::GetByName(GetEventCommandRaw());
|
||||||
|
}}}
|
||||||
|
};
|
||||||
[config] bool volatile;
|
[config] bool volatile;
|
||||||
[config] double flapping_threshold {
|
[config] double flapping_threshold {
|
||||||
default {{{ return 30; }}}
|
default {{{ return 30; }}}
|
||||||
|
@ -137,7 +151,11 @@ abstract class Checkable : CustomVarObject
|
||||||
get {{{ return false; }}}
|
get {{{ return false; }}}
|
||||||
};
|
};
|
||||||
|
|
||||||
[config] name(Endpoint) command_endpoint (CommandEndpointRaw);
|
[config, navigation] name(Endpoint) command_endpoint (CommandEndpointRaw) {
|
||||||
|
navigate {{{
|
||||||
|
return Endpoint::GetByName(GetCommandEndpointRaw());
|
||||||
|
}}}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,13 @@ class Dependency : CustomVarObject < DependencyNameComposer
|
||||||
load_after Host;
|
load_after Host;
|
||||||
load_after Service;
|
load_after Service;
|
||||||
|
|
||||||
[config, required] name(Host) child_host_name;
|
[config, required, navigation(child_host)] name(Host) child_host_name {
|
||||||
[config] String child_service_name {
|
navigate {{{
|
||||||
|
return Host::GetByName(GetChildHostName());
|
||||||
|
}}}
|
||||||
|
};
|
||||||
|
|
||||||
|
[config, navigation(child_service)] String child_service_name {
|
||||||
track {{{
|
track {{{
|
||||||
if (!oldValue.IsEmpty()) {
|
if (!oldValue.IsEmpty()) {
|
||||||
Service::Ptr service = Service::GetByNamePair(GetParentHostName(), oldValue);
|
Service::Ptr service = Service::GetByNamePair(GetParentHostName(), oldValue);
|
||||||
|
@ -53,10 +58,22 @@ class Dependency : CustomVarObject < DependencyNameComposer
|
||||||
DependencyGraph::RemoveDependency(this, service.get());
|
DependencyGraph::RemoveDependency(this, service.get());
|
||||||
}
|
}
|
||||||
}}}
|
}}}
|
||||||
|
navigate {{{
|
||||||
|
if (GetChildServiceName().IsEmpty())
|
||||||
|
return Service::Ptr();
|
||||||
|
|
||||||
|
Host::Ptr host = Host::GetByName(GetChildHostName());
|
||||||
|
return host->GetServiceByShortName(GetChildServiceName());
|
||||||
|
}}}
|
||||||
};
|
};
|
||||||
|
|
||||||
[config, required] name(Host) parent_host_name;
|
[config, required, navigation(parent_host)] name(Host) parent_host_name {
|
||||||
[config] String parent_service_name {
|
navigate {{{
|
||||||
|
return Host::GetByName(GetParentHostName());
|
||||||
|
}}}
|
||||||
|
};
|
||||||
|
|
||||||
|
[config, navigation(parent_service)] String parent_service_name {
|
||||||
track {{{
|
track {{{
|
||||||
if (!oldValue.IsEmpty()) {
|
if (!oldValue.IsEmpty()) {
|
||||||
Service::Ptr service = Service::GetByNamePair(GetParentHostName(), oldValue);
|
Service::Ptr service = Service::GetByNamePair(GetParentHostName(), oldValue);
|
||||||
|
@ -68,9 +85,20 @@ class Dependency : CustomVarObject < DependencyNameComposer
|
||||||
DependencyGraph::RemoveDependency(this, service.get());
|
DependencyGraph::RemoveDependency(this, service.get());
|
||||||
}
|
}
|
||||||
}}}
|
}}}
|
||||||
|
navigate {{{
|
||||||
|
if (GetParentServiceName().IsEmpty())
|
||||||
|
return Service::Ptr();
|
||||||
|
|
||||||
|
Host::Ptr host = Host::GetByName(GetParentHostName());
|
||||||
|
return host->GetServiceByShortName(GetParentServiceName());
|
||||||
|
}}}
|
||||||
};
|
};
|
||||||
|
|
||||||
[config] name(TimePeriod) period (PeriodRaw);
|
[config, navigation] name(TimePeriod) period (PeriodRaw) {
|
||||||
|
navigate {{{
|
||||||
|
return TimePeriod::GetByName(GetPeriodRaw());
|
||||||
|
}}}
|
||||||
|
};
|
||||||
|
|
||||||
[config] array(double) states;
|
[config] array(double) states;
|
||||||
int state_filter_real (StateFilter);
|
int state_filter_real (StateFilter);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "icinga/customvarobject.hpp"
|
#include "icinga/customvarobject.hpp"
|
||||||
|
#impl_include "icinga/notificationcommand.hpp"
|
||||||
#impl_include "icinga/service.hpp"
|
#impl_include "icinga/service.hpp"
|
||||||
|
|
||||||
library icinga;
|
library icinga;
|
||||||
|
@ -39,11 +40,19 @@ class Notification : CustomVarObject < NotificationNameComposer
|
||||||
load_after Host;
|
load_after Host;
|
||||||
load_after Service;
|
load_after Service;
|
||||||
|
|
||||||
[config, protected, required] name(NotificationCommand) command (CommandRaw);
|
[config, protected, required, navigation] name(NotificationCommand) command (CommandRaw) {
|
||||||
|
navigate {{{
|
||||||
|
return NotificationCommand::GetByName(GetCommandRaw());
|
||||||
|
}}}
|
||||||
|
};
|
||||||
[config] double interval {
|
[config] double interval {
|
||||||
default {{{ return 1800; }}}
|
default {{{ return 1800; }}}
|
||||||
};
|
};
|
||||||
[config] name(TimePeriod) period (PeriodRaw);
|
[config, navigation] name(TimePeriod) period (PeriodRaw) {
|
||||||
|
navigate {{{
|
||||||
|
return TimePeriod::GetByName(GetPeriodRaw());
|
||||||
|
}}}
|
||||||
|
};
|
||||||
[config, protected] array(name(User)) users (UsersRaw);
|
[config, protected] array(name(User)) users (UsersRaw);
|
||||||
[config, protected] array(name(UserGroup)) user_groups (UserGroupsRaw);
|
[config, protected] array(name(UserGroup)) user_groups (UserGroupsRaw);
|
||||||
[config] Dictionary::Ptr times;
|
[config] Dictionary::Ptr times;
|
||||||
|
@ -51,8 +60,12 @@ class Notification : CustomVarObject < NotificationNameComposer
|
||||||
int type_filter_real (TypeFilter);
|
int type_filter_real (TypeFilter);
|
||||||
[config] array(double) states;
|
[config] array(double) states;
|
||||||
int state_filter_real (StateFilter);
|
int state_filter_real (StateFilter);
|
||||||
[config, protected, required] name(Host) host_name;
|
[config, protected, required, navigation(host)] name(Host) host_name {
|
||||||
[config, protected] String service_name {
|
navigate {{{
|
||||||
|
return Host::GetByName(GetHostName());
|
||||||
|
}}}
|
||||||
|
};
|
||||||
|
[config, protected, navigation(service)] String service_name {
|
||||||
track {{{
|
track {{{
|
||||||
if (!oldValue.IsEmpty()) {
|
if (!oldValue.IsEmpty()) {
|
||||||
Service::Ptr service = Service::GetByNamePair(GetHostName(), oldValue);
|
Service::Ptr service = Service::GetByNamePair(GetHostName(), oldValue);
|
||||||
|
@ -64,6 +77,13 @@ class Notification : CustomVarObject < NotificationNameComposer
|
||||||
DependencyGraph::RemoveDependency(this, service.get());
|
DependencyGraph::RemoveDependency(this, service.get());
|
||||||
}
|
}
|
||||||
}}}
|
}}}
|
||||||
|
navigate {{{
|
||||||
|
if (GetServiceName().IsEmpty())
|
||||||
|
return Service::Ptr();
|
||||||
|
|
||||||
|
Host::Ptr host = Host::GetByName(GetHostName());
|
||||||
|
return host->GetServiceByShortName(GetServiceName());
|
||||||
|
}}}
|
||||||
};
|
};
|
||||||
|
|
||||||
[state] Array::Ptr notified_users {
|
[state] Array::Ptr notified_users {
|
||||||
|
@ -75,7 +95,11 @@ class Notification : CustomVarObject < NotificationNameComposer
|
||||||
[state, set_protected] Value notification_number;
|
[state, set_protected] Value notification_number;
|
||||||
[state] double last_problem_notification;
|
[state] double last_problem_notification;
|
||||||
|
|
||||||
[config] name(Endpoint) command_endpoint (CommandEndpointRaw);
|
[config, navigation] name(Endpoint) command_endpoint (CommandEndpointRaw) {
|
||||||
|
navigate {{{
|
||||||
|
return Endpoint::GetByName(GetCommandEndpointRaw());
|
||||||
|
}}}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
validator Notification {
|
validator Notification {
|
||||||
|
|
|
@ -39,8 +39,12 @@ class ScheduledDowntime : CustomVarObject < ScheduledDowntimeNameComposer
|
||||||
load_after Host;
|
load_after Host;
|
||||||
load_after Service;
|
load_after Service;
|
||||||
|
|
||||||
[config, protected, required] name(Host) host_name;
|
[config, protected, required, navigation(host)] name(Host) host_name {
|
||||||
[config, protected] String service_name {
|
navigate {{{
|
||||||
|
return Host::GetByName(GetHostName());
|
||||||
|
}}}
|
||||||
|
};
|
||||||
|
[config, protected, navigation(service)] String service_name {
|
||||||
track {{{
|
track {{{
|
||||||
if (!oldValue.IsEmpty()) {
|
if (!oldValue.IsEmpty()) {
|
||||||
Service::Ptr service = Service::GetByNamePair(GetHostName(), oldValue);
|
Service::Ptr service = Service::GetByNamePair(GetHostName(), oldValue);
|
||||||
|
@ -52,6 +56,13 @@ class ScheduledDowntime : CustomVarObject < ScheduledDowntimeNameComposer
|
||||||
DependencyGraph::RemoveDependency(this, service.get());
|
DependencyGraph::RemoveDependency(this, service.get());
|
||||||
}
|
}
|
||||||
}}}
|
}}}
|
||||||
|
navigate {{{
|
||||||
|
if (GetServiceName().IsEmpty())
|
||||||
|
return Service::Ptr();
|
||||||
|
|
||||||
|
Host::Ptr host = Host::GetByName(GetHostName());
|
||||||
|
return host->GetServiceByShortName(GetServiceName());
|
||||||
|
}}}
|
||||||
};
|
};
|
||||||
|
|
||||||
[config, required] String author;
|
[config, required] String author;
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
|
|
||||||
static Service::Ptr GetByNamePair(const String& hostName, const String& serviceName);
|
static Service::Ptr GetByNamePair(const String& hostName, const String& serviceName);
|
||||||
|
|
||||||
Host::Ptr GetHost(void) const;
|
virtual Host::Ptr GetHost(void) const override;
|
||||||
|
|
||||||
virtual bool ResolveMacro(const String& macro, const CheckResult::Ptr& cr, Value *result) const override;
|
virtual bool ResolveMacro(const String& macro, const CheckResult::Ptr& cr, Value *result) const override;
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,12 @@ class Service : Checkable < ServiceNameComposer
|
||||||
}}}
|
}}}
|
||||||
};
|
};
|
||||||
[config, required] name(Host) host_name;
|
[config, required] name(Host) host_name;
|
||||||
|
[no_storage, navigation] Host::Ptr host {
|
||||||
|
get;
|
||||||
|
navigate {{{
|
||||||
|
return GetHost();
|
||||||
|
}}}
|
||||||
|
};
|
||||||
[enum, no_storage] ServiceState "state" {
|
[enum, no_storage] ServiceState "state" {
|
||||||
get {{{
|
get {{{
|
||||||
return GetStateRaw();
|
return GetStateRaw();
|
||||||
|
|
|
@ -38,7 +38,12 @@ class User : CustomVarObject
|
||||||
[config] array(name(UserGroup)) groups {
|
[config] array(name(UserGroup)) groups {
|
||||||
default {{{ return new Array(); }}}
|
default {{{ return new Array(); }}}
|
||||||
};
|
};
|
||||||
[config] name(TimePeriod) period (PeriodRaw);
|
[config, navigation] name(TimePeriod) period (PeriodRaw) {
|
||||||
|
navigate {{{
|
||||||
|
return TimePeriod::GetByName(GetPeriodRaw());
|
||||||
|
}}}
|
||||||
|
};
|
||||||
|
|
||||||
[config] array(double) types;
|
[config] array(double) types;
|
||||||
int type_filter_real (TypeFilter);
|
int type_filter_real (TypeFilter);
|
||||||
[config] array(double) states;
|
[config] array(double) states;
|
||||||
|
|
|
@ -78,10 +78,28 @@ String ConfigObjectTargetProvider::GetPluralName(const String& type) const
|
||||||
return Type::GetByName(type)->GetPluralName();
|
return Type::GetByName(type)->GetPluralName();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FilteredAddTarget(ScriptFrame& frame, const String& varName, Expression *ufilter, std::vector<Value>& result, const Value& target)
|
static void FilteredAddTarget(ScriptFrame& frame, Expression *ufilter, std::vector<Value>& result, const Object::Ptr& target)
|
||||||
{
|
{
|
||||||
|
Type::Ptr type = target->GetReflectionType();
|
||||||
|
String varName = type->GetName();
|
||||||
|
boost::algorithm::to_lower(varName);
|
||||||
|
|
||||||
frame.Locals->Set(varName, target);
|
frame.Locals->Set(varName, target);
|
||||||
|
|
||||||
|
for (int fid = 0; fid < type->GetFieldCount(); fid++) {
|
||||||
|
Field field = type->GetFieldInfo(fid);
|
||||||
|
|
||||||
|
if ((field.Attributes & FANavigation) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Object::Ptr joinedObj = target->NavigateField(fid);
|
||||||
|
|
||||||
|
varName = field.TypeName;
|
||||||
|
boost::algorithm::to_lower(varName);
|
||||||
|
|
||||||
|
frame.Locals->Set(varName, joinedObj);
|
||||||
|
}
|
||||||
|
|
||||||
if (Convert::ToBool(ufilter->Evaluate(frame)))
|
if (Convert::ToBool(ufilter->Evaluate(frame)))
|
||||||
result.push_back(target);
|
result.push_back(target);
|
||||||
}
|
}
|
||||||
|
@ -153,11 +171,8 @@ std::vector<Value> FilterUtility::GetFilterTargets(const QueryDescription& qd, c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String varName = type;
|
|
||||||
boost::algorithm::to_lower(varName);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
provider->FindTargets(type, boost::bind(&FilteredAddTarget, boost::ref(frame), varName, ufilter, boost::ref(result), _1));
|
provider->FindTargets(type, boost::bind(&FilteredAddTarget, boost::ref(frame), ufilter, boost::ref(result), _1));
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
delete ufilter;
|
delete ufilter;
|
||||||
throw;
|
throw;
|
||||||
|
|
|
@ -46,8 +46,15 @@ bool StatusQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& re
|
||||||
QueryDescription qd;
|
QueryDescription qd;
|
||||||
qd.Types.insert(type->GetName());
|
qd.Types.insert(type->GetName());
|
||||||
|
|
||||||
std::vector<String> joinTypes;
|
std::vector<String> joinAttrs;
|
||||||
joinTypes.push_back(type->GetName());
|
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);
|
Dictionary::Ptr params = HttpUtility::FetchRequestParameters(request);
|
||||||
|
|
||||||
|
@ -80,17 +87,44 @@ bool StatusQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& re
|
||||||
Dictionary::Ptr resultAttrs = new Dictionary();
|
Dictionary::Ptr resultAttrs = new Dictionary();
|
||||||
result1->Set("attrs", resultAttrs);
|
result1->Set("attrs", resultAttrs);
|
||||||
|
|
||||||
BOOST_FOREACH(const String& joinType, joinTypes) {
|
BOOST_FOREACH(const String& joinAttr, joinAttrs) {
|
||||||
String prefix = joinType;
|
Object::Ptr joinedObj;
|
||||||
|
String prefix;
|
||||||
|
|
||||||
|
if (joinAttr.IsEmpty()) {
|
||||||
|
joinedObj = obj;
|
||||||
|
prefix = type->GetName();
|
||||||
|
} else {
|
||||||
|
int fid = type->GetFieldId(joinAttr);
|
||||||
|
joinedObj = static_cast<Object::Ptr>(obj)->NavigateField(fid);
|
||||||
|
|
||||||
|
if (!joinedObj)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Field field = type->GetFieldInfo(fid);
|
||||||
|
prefix = field.NavigationName;
|
||||||
|
}
|
||||||
|
|
||||||
boost::algorithm::to_lower(prefix);
|
boost::algorithm::to_lower(prefix);
|
||||||
|
|
||||||
for (int fid = 0; fid < type->GetFieldCount(); fid++) {
|
Type::Ptr joinedType = joinedObj->GetReflectionType();
|
||||||
Field field = type->GetFieldInfo(fid);
|
|
||||||
|
for (int fid = 0; fid < joinedType->GetFieldCount(); fid++) {
|
||||||
|
Field field = joinedType->GetFieldInfo(fid);
|
||||||
String aname = prefix + "." + field.Name;
|
String aname = prefix + "." + field.Name;
|
||||||
if (!attrs.empty() && attrs.find(aname) == attrs.end())
|
if (!attrs.empty() && attrs.find(aname) == attrs.end())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Value val = static_cast<Object::Ptr>(obj)->GetField(fid);
|
Value val = joinedObj->GetField(fid);
|
||||||
|
|
||||||
|
/* hide internal navigation fields */
|
||||||
|
if (field.Attributes & FANavigation) {
|
||||||
|
Value nval = joinedObj->NavigateField(fid);
|
||||||
|
|
||||||
|
if (val == nval)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Value sval = Serialize(val, FAConfig | FAState);
|
Value sval = Serialize(val, FAConfig | FAState);
|
||||||
resultAttrs->Set(aname, sval);
|
resultAttrs->Set(aname, sval);
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,6 +138,8 @@ bool TypeQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& requ
|
||||||
fieldInfo->Set("type", field.TypeName);
|
fieldInfo->Set("type", field.TypeName);
|
||||||
if (field.RefTypeName)
|
if (field.RefTypeName)
|
||||||
fieldInfo->Set("ref_type", field.RefTypeName);
|
fieldInfo->Set("ref_type", field.RefTypeName);
|
||||||
|
if (field.Attributes & FANavigation)
|
||||||
|
fieldInfo->Set("navigation_name", field.NavigationName);
|
||||||
fieldInfo->Set("array_rank", field.ArrayRank);
|
fieldInfo->Set("array_rank", field.ArrayRank);
|
||||||
|
|
||||||
Dictionary::Ptr attributeInfo = new Dictionary();
|
Dictionary::Ptr attributeInfo = new Dictionary();
|
||||||
|
@ -147,7 +149,7 @@ bool TypeQueryHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& requ
|
||||||
attributeInfo->Set("state", static_cast<bool>(field.Attributes & FAState));
|
attributeInfo->Set("state", static_cast<bool>(field.Attributes & FAState));
|
||||||
attributeInfo->Set("internal", static_cast<bool>(field.Attributes & FAInternal));
|
attributeInfo->Set("internal", static_cast<bool>(field.Attributes & FAInternal));
|
||||||
attributeInfo->Set("required", static_cast<bool>(field.Attributes & FARequired));
|
attributeInfo->Set("required", static_cast<bool>(field.Attributes & FARequired));
|
||||||
|
attributeInfo->Set("navigation", static_cast<bool>(field.Attributes & FANavigation));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,12 @@ namespace icinga
|
||||||
|
|
||||||
class Zone : ConfigObject
|
class Zone : ConfigObject
|
||||||
{
|
{
|
||||||
[config] name(Zone) parent (ParentRaw);
|
[config, navigation] name(Zone) parent (ParentRaw) {
|
||||||
|
navigate {{{
|
||||||
|
return Zone::GetByName(GetParentRaw());
|
||||||
|
}}}
|
||||||
|
};
|
||||||
|
|
||||||
[config] array(name(Endpoint)) endpoints (EndpointsRaw);
|
[config] array(name(Endpoint)) endpoints (EndpointsRaw);
|
||||||
[config] bool global;
|
[config] bool global;
|
||||||
};
|
};
|
||||||
|
|
|
@ -145,6 +145,7 @@ set_protected { yylval->num = FASetProtected; return T_FIELD_ATTRIBUTE; }
|
||||||
protected { yylval->num = FAGetProtected | FASetProtected; return T_FIELD_ATTRIBUTE; }
|
protected { yylval->num = FAGetProtected | FASetProtected; return T_FIELD_ATTRIBUTE; }
|
||||||
internal { yylval->num = FAInternal; return T_FIELD_ATTRIBUTE; }
|
internal { yylval->num = FAInternal; return T_FIELD_ATTRIBUTE; }
|
||||||
no_storage { yylval->num = FANoStorage; return T_FIELD_ATTRIBUTE; }
|
no_storage { yylval->num = FANoStorage; return T_FIELD_ATTRIBUTE; }
|
||||||
|
navigation { return T_NAVIGATION; }
|
||||||
validator { return T_VALIDATOR; }
|
validator { return T_VALIDATOR; }
|
||||||
required { return T_REQUIRED; }
|
required { return T_REQUIRED; }
|
||||||
name { return T_NAME; }
|
name { return T_NAME; }
|
||||||
|
@ -153,8 +154,9 @@ default { yylval->num = FTDefault; return T_FIELD_ACCESSOR_TYPE; }
|
||||||
get { yylval->num = FTGet; return T_FIELD_ACCESSOR_TYPE; }
|
get { yylval->num = FTGet; return T_FIELD_ACCESSOR_TYPE; }
|
||||||
set { yylval->num = FTSet; return T_FIELD_ACCESSOR_TYPE; }
|
set { yylval->num = FTSet; return T_FIELD_ACCESSOR_TYPE; }
|
||||||
track { yylval->num = FTTrack; return T_FIELD_ACCESSOR_TYPE; }
|
track { yylval->num = FTTrack; return T_FIELD_ACCESSOR_TYPE; }
|
||||||
|
navigate { yylval->num = FTNavigate; return T_FIELD_ACCESSOR_TYPE; }
|
||||||
\"[^\"]+\" { yylval->text = strdup(yytext + 1); yylval->text[strlen(yylval->text) - 1] = '\0'; return T_STRING; }
|
\"[^\"]+\" { yylval->text = strdup(yytext + 1); yylval->text[strlen(yylval->text) - 1] = '\0'; return T_STRING; }
|
||||||
\<[^>]+\> { yylval->text = strdup(yytext + 1); yylval->text[strlen(yylval->text) - 1] = '\0'; return T_ANGLE_STRING; }
|
\<[^ \>]*\> { yylval->text = strdup(yytext + 1); yylval->text[strlen(yylval->text) - 1] = '\0'; return T_ANGLE_STRING; }
|
||||||
[a-zA-Z_][:a-zA-Z0-9\-_]* { yylval->text = strdup(yytext); return T_IDENTIFIER; }
|
[a-zA-Z_][:a-zA-Z0-9\-_]* { yylval->text = strdup(yytext); return T_IDENTIFIER; }
|
||||||
|
|
||||||
. return yytext[0];
|
. return yytext[0];
|
||||||
|
|
|
@ -65,6 +65,7 @@ using namespace icinga;
|
||||||
%token T_NAMESPACE "namespace (T_NAMESPACE)"
|
%token T_NAMESPACE "namespace (T_NAMESPACE)"
|
||||||
%token T_VALIDATOR "validator (T_VALIDATOR)"
|
%token T_VALIDATOR "validator (T_VALIDATOR)"
|
||||||
%token T_REQUIRED "required (T_REQUIRED)"
|
%token T_REQUIRED "required (T_REQUIRED)"
|
||||||
|
%token T_NAVIGATION "navigation (T_NAVIGATION)"
|
||||||
%token T_NAME "name (T_NAME)"
|
%token T_NAME "name (T_NAME)"
|
||||||
%token T_ARRAY "array (T_ARRAY)"
|
%token T_ARRAY "array (T_ARRAY)"
|
||||||
%token T_STRING "string (T_STRING)"
|
%token T_STRING "string (T_STRING)"
|
||||||
|
@ -89,9 +90,9 @@ using namespace icinga;
|
||||||
%type <text> angle_impl_include
|
%type <text> angle_impl_include
|
||||||
%type <text> code
|
%type <text> code
|
||||||
%type <num> T_FIELD_ATTRIBUTE
|
%type <num> T_FIELD_ATTRIBUTE
|
||||||
%type <num> field_attribute
|
%type <field> field_attribute
|
||||||
%type <num> field_attributes
|
%type <field> field_attributes
|
||||||
%type <num> field_attribute_list
|
%type <field> field_attribute_list
|
||||||
%type <num> T_FIELD_ACCESSOR_TYPE
|
%type <num> T_FIELD_ACCESSOR_TYPE
|
||||||
%type <num> T_CLASS_ATTRIBUTE
|
%type <num> T_CLASS_ATTRIBUTE
|
||||||
%type <num> class_attribute_list
|
%type <num> class_attribute_list
|
||||||
|
@ -328,9 +329,7 @@ field_type: identifier
|
||||||
|
|
||||||
class_field: field_attribute_list field_type identifier alternative_name_specifier field_accessor_list ';'
|
class_field: field_attribute_list field_type identifier alternative_name_specifier field_accessor_list ';'
|
||||||
{
|
{
|
||||||
Field *field = new Field();
|
Field *field = $1;
|
||||||
|
|
||||||
field->Attributes = $1;
|
|
||||||
|
|
||||||
if ((field->Attributes & (FAConfig | FAState)) == 0)
|
if ((field->Attributes & (FAConfig | FAState)) == 0)
|
||||||
field->Attributes |= FAEphemeral;
|
field->Attributes |= FAEphemeral;
|
||||||
|
@ -363,6 +362,10 @@ class_field: field_attribute_list field_type identifier alternative_name_specifi
|
||||||
case FTTrack:
|
case FTTrack:
|
||||||
field->TrackAccessor = it->Accessor;
|
field->TrackAccessor = it->Accessor;
|
||||||
break;
|
break;
|
||||||
|
case FTNavigate:
|
||||||
|
field->NavigateAccessor = it->Accessor;
|
||||||
|
field->PureNavigateAccessor = it->Pure;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,7 +395,7 @@ alternative_name_specifier: /* empty */
|
||||||
|
|
||||||
field_attribute_list: /* empty */
|
field_attribute_list: /* empty */
|
||||||
{
|
{
|
||||||
$$ = 0;
|
$$ = new Field();
|
||||||
}
|
}
|
||||||
| '[' field_attributes ']'
|
| '[' field_attributes ']'
|
||||||
{
|
{
|
||||||
|
@ -402,21 +405,39 @@ field_attribute_list: /* empty */
|
||||||
|
|
||||||
field_attribute: T_FIELD_ATTRIBUTE
|
field_attribute: T_FIELD_ATTRIBUTE
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = new Field();
|
||||||
|
$$->Attributes = $1;
|
||||||
}
|
}
|
||||||
| T_REQUIRED
|
| T_REQUIRED
|
||||||
{
|
{
|
||||||
$$ = FARequired;
|
$$ = new Field();
|
||||||
|
$$->Attributes = FARequired;
|
||||||
|
}
|
||||||
|
| T_NAVIGATION '(' identifier ')'
|
||||||
|
{
|
||||||
|
$$ = new Field();
|
||||||
|
$$->Attributes = FANavigation;
|
||||||
|
$$->NavigationName = $3;
|
||||||
|
std::free($3);
|
||||||
|
}
|
||||||
|
| T_NAVIGATION
|
||||||
|
{
|
||||||
|
$$ = new Field();
|
||||||
|
$$->Attributes = FANavigation;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
field_attributes: /* empty */
|
field_attributes: /* empty */
|
||||||
{
|
{
|
||||||
$$ = 0;
|
$$ = new Field();
|
||||||
}
|
}
|
||||||
| field_attributes ',' field_attribute
|
| field_attributes ',' field_attribute
|
||||||
{
|
{
|
||||||
$$ = $1 | $3;
|
$$ = $1;
|
||||||
|
$$->Attributes |= $3->Attributes;
|
||||||
|
if (!$3->NavigationName.empty())
|
||||||
|
$$->NavigationName = $3->NavigationName;
|
||||||
|
delete $3;
|
||||||
}
|
}
|
||||||
| field_attribute
|
| field_attribute
|
||||||
{
|
{
|
||||||
|
|
|
@ -366,7 +366,7 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
|
||||||
nameref = "NULL";
|
nameref = "NULL";
|
||||||
|
|
||||||
m_Impl << "\t\t" << "case " << num << ":" << std::endl
|
m_Impl << "\t\t" << "case " << num << ":" << std::endl
|
||||||
<< "\t\t\t" << "return Field(" << num << ", \"" << ftype << "\", \"" << it->Name << "\", " << nameref << ", " << it->Attributes << ", " << it->Type.ArrayRank << ");" << std::endl;
|
<< "\t\t\t" << "return Field(" << num << ", \"" << ftype << "\", \"" << it->Name << "\", \"" << (it->NavigationName.empty() ? it->Name : it->NavigationName) << "\", " << nameref << ", " << it->Attributes << ", " << it->Type.ArrayRank << ");" << std::endl;
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,6 +695,42 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
|
||||||
|
|
||||||
m_Impl << "}" << std::endl << std::endl;
|
m_Impl << "}" << std::endl << std::endl;
|
||||||
|
|
||||||
|
/* NavigateField */
|
||||||
|
m_Header << "protected:" << std::endl
|
||||||
|
<< "\t" << "virtual Object::Ptr NavigateField(int id) const override;" << std::endl;
|
||||||
|
|
||||||
|
m_Impl << "Object::Ptr ObjectImpl<" << klass.Name << ">::NavigateField(int id) const" << std::endl
|
||||||
|
<< "{" << std::endl;
|
||||||
|
|
||||||
|
if (!klass.Parent.empty())
|
||||||
|
m_Impl << "\t" << "int real_id = id - " << klass.Parent << "::TypeInstance->GetFieldCount(); " << std::endl
|
||||||
|
<< "\t" << "if (real_id < 0) { return " << klass.Parent << "::NavigateField(id); }" << std::endl;
|
||||||
|
|
||||||
|
m_Impl << "\t" << "switch (";
|
||||||
|
|
||||||
|
if (!klass.Parent.empty())
|
||||||
|
m_Impl << "real_id";
|
||||||
|
else
|
||||||
|
m_Impl << "id";
|
||||||
|
|
||||||
|
m_Impl << ") {" << std::endl;
|
||||||
|
|
||||||
|
num = 0;
|
||||||
|
for (it = klass.Fields.begin(); it != klass.Fields.end(); it++) {
|
||||||
|
if (it->Attributes & FANavigation) {
|
||||||
|
m_Impl << "\t\t" << "case " << num << ":" << std::endl
|
||||||
|
<< "\t\t\t" << "return Navigate" << it->GetFriendlyName() << "();" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Impl << "\t\t" << "default:" << std::endl
|
||||||
|
<< "\t\t\t" << "throw std::runtime_error(\"Invalid field ID.\");" << std::endl
|
||||||
|
<< "\t" << "}" << std::endl;
|
||||||
|
|
||||||
|
m_Impl << "}" << std::endl << std::endl;
|
||||||
|
|
||||||
/* getters */
|
/* getters */
|
||||||
for (it = klass.Fields.begin(); it != klass.Fields.end(); it++) {
|
for (it = klass.Fields.begin(); it != klass.Fields.end(); it++) {
|
||||||
std::string prot;
|
std::string prot;
|
||||||
|
@ -811,6 +847,31 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&)
|
||||||
m_Impl << "}" << std::endl << std::endl;
|
m_Impl << "}" << std::endl << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* navigation */
|
||||||
|
for (it = klass.Fields.begin(); it != klass.Fields.end(); it++) {
|
||||||
|
if ((it->Attributes & FANavigation) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
m_Header << "public:" << std::endl
|
||||||
|
<< "\t" << "virtual Object::Ptr Navigate" << it->GetFriendlyName() << "(void) const";
|
||||||
|
|
||||||
|
if (it->PureNavigateAccessor) {
|
||||||
|
m_Header << " = 0;" << std::endl;
|
||||||
|
} else {
|
||||||
|
m_Header << ";" << std::endl;
|
||||||
|
|
||||||
|
m_Impl << "Object::Ptr ObjectImpl<" << klass.Name << ">::Navigate" << it->GetFriendlyName() << "(void) const" << std::endl
|
||||||
|
<< "{" << std::endl;
|
||||||
|
|
||||||
|
if (it->NavigateAccessor.empty())
|
||||||
|
m_Impl << "\t" << "return Get" << it->GetFriendlyName() << "();" << std::endl;
|
||||||
|
else
|
||||||
|
m_Impl << "\t" << it->NavigateAccessor << std::endl;
|
||||||
|
|
||||||
|
m_Impl << "}" << std::endl << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* start/stop */
|
/* start/stop */
|
||||||
if (needs_tracking) {
|
if (needs_tracking) {
|
||||||
m_Header << "virtual void Start(void) override;" << std::endl
|
m_Header << "virtual void Start(void) override;" << std::endl
|
||||||
|
|
|
@ -43,7 +43,8 @@ enum FieldAccessorType
|
||||||
FTGet,
|
FTGet,
|
||||||
FTSet,
|
FTSet,
|
||||||
FTDefault,
|
FTDefault,
|
||||||
FTTrack
|
FTTrack,
|
||||||
|
FTNavigate
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FieldAccessor
|
struct FieldAccessor
|
||||||
|
@ -69,7 +70,8 @@ enum FieldAttribute
|
||||||
FAInternal = 64,
|
FAInternal = 64,
|
||||||
FANoStorage = 128,
|
FANoStorage = 128,
|
||||||
FALoadDependency = 256,
|
FALoadDependency = 256,
|
||||||
FARequired = 512
|
FARequired = 512,
|
||||||
|
FANavigation = 1024
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FieldType
|
struct FieldType
|
||||||
|
@ -116,9 +118,12 @@ struct Field
|
||||||
bool PureSetAccessor;
|
bool PureSetAccessor;
|
||||||
std::string DefaultAccessor;
|
std::string DefaultAccessor;
|
||||||
std::string TrackAccessor;
|
std::string TrackAccessor;
|
||||||
|
std::string NavigationName;
|
||||||
|
std::string NavigateAccessor;
|
||||||
|
bool PureNavigateAccessor;
|
||||||
|
|
||||||
Field(void)
|
Field(void)
|
||||||
: Attributes(0), PureGetAccessor(false), PureSetAccessor(false)
|
: Attributes(0), PureGetAccessor(false), PureSetAccessor(false), PureNavigateAccessor(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
inline std::string GetFriendlyName(void) const
|
inline std::string GetFriendlyName(void) const
|
||||||
|
|
Loading…
Reference in New Issue