-
Notifications
You must be signed in to change notification settings - Fork 576
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix update execution message discarded. refs #8616 #8627
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -761,9 +761,18 @@ Value ClusterEvents::ExecuteCommandAPIHandler(const MessageOrigin::Ptr& origin, | |
} | ||
} | ||
|
||
String executionUuid = params->Get("source"); | ||
|
||
if (params->Contains("endpoint")) { | ||
Endpoint::Ptr execEndpoint = Endpoint::GetByName(params->Get("endpoint")); | ||
|
||
if (!execEndpoint) { | ||
Log(LogWarning, "ClusterEvents") | ||
<< "Discarding 'execute command' message " << executionUuid | ||
<< ": Endpoint " << params->Get("endpoint") << " does not exist"; | ||
return Empty; | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So far so good... |
||
if (execEndpoint != Endpoint::GetLocalEndpoint()) { | ||
Zone::Ptr endpointZone = execEndpoint->GetZone(); | ||
Zone::Ptr localZone = Zone::GetLocalZone(); | ||
|
@@ -782,7 +791,7 @@ Value ClusterEvents::ExecuteCommandAPIHandler(const MessageOrigin::Ptr& origin, | |
if (!(childEndpoint->GetCapabilities() & (uint_fast64_t)ApiCapabilities::ExecuteArbitraryCommand)) { | ||
double now = Utility::GetTime(); | ||
Dictionary::Ptr executedParams = new Dictionary(); | ||
executedParams->Set("execution", params->Get("source")); | ||
executedParams->Set("execution", executionUuid); | ||
executedParams->Set("host", params->Get("host")); | ||
|
||
if (params->Contains("service")) | ||
|
@@ -803,6 +812,62 @@ Value ClusterEvents::ExecuteCommandAPIHandler(const MessageOrigin::Ptr& origin, | |
return Empty; | ||
} | ||
} | ||
|
||
Checkable::Ptr checkable; | ||
Host::Ptr host = Host::GetByName(params->Get("host")); | ||
if (!host) { | ||
Log(LogWarning, "ClusterEvents") | ||
<< "Discarding 'execute command' message " << executionUuid | ||
<< ": host " << params->Get("host") << " does not exist"; | ||
return Empty; | ||
} | ||
|
||
if (params->Contains("service")) | ||
checkable = host->GetServiceByShortName(params->Get("service")); | ||
else | ||
checkable = host; | ||
|
||
if (!checkable) { | ||
String checkableName = host->GetName(); | ||
if (params->Contains("service")) | ||
checkableName += "!" + params->Get("service"); | ||
|
||
Log(LogWarning, "ClusterEvents") | ||
<< "Discarding 'execute command' message " << executionUuid | ||
<< ": " << checkableName << " does not exist"; | ||
return Empty; | ||
} | ||
|
||
/* Return an error when the endpointZone is different than the child zone and | ||
* the child zone can't access the checkable. | ||
* The zones are checked to allow for the case where command_endpoint is specified in the checkable | ||
* but checkable is not actually present in the agent. | ||
*/ | ||
if (!zone->CanAccessObject(checkable) && zone != endpointZone) { | ||
double now = Utility::GetTime(); | ||
Dictionary::Ptr executedParams = new Dictionary(); | ||
executedParams->Set("execution", executionUuid); | ||
executedParams->Set("host", params->Get("host")); | ||
|
||
if (params->Contains("service")) | ||
executedParams->Set("service", params->Get("service")); | ||
|
||
executedParams->Set("exit", 126); | ||
executedParams->Set( | ||
"output", | ||
"Zone '" + zone->GetName() + "' cannot access to checkable '" + checkable->GetName() + "'." | ||
); | ||
executedParams->Set("start", now); | ||
executedParams->Set("end", now); | ||
|
||
Dictionary::Ptr executedMessage = new Dictionary(); | ||
executedMessage->Set("jsonrpc", "2.0"); | ||
executedMessage->Set("method", "event::ExecutedCommand"); | ||
executedMessage->Set("params", executedParams); | ||
|
||
listener->RelayMessage(nullptr, nullptr, executedMessage, true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Huh? nullptr, nullptr? Not... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be honest, I haven't put much thought into these parameters here as the existing However, are you sure about origin? This is sending a response that originates here, so with the origin of the incoming message, that might prevent the response from being sent back. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From what I tested, I agree with Julian, using
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops. 😅 🐘 |
||
return Empty; | ||
} | ||
} | ||
} | ||
|
||
|
@@ -1179,13 +1244,6 @@ Value ClusterEvents::ExecutedCommandAPIHandler(const MessageOrigin::Ptr& origin, | |
|
||
ObjectLock oLock (checkable); | ||
|
||
if (origin->FromZone && !origin->FromZone->CanAccessObject(checkable)) { | ||
Log(LogNotice, "ClusterEvents") | ||
<< "Discarding 'update executions API handler' message for checkable '" << checkable->GetName() | ||
<< "' from '" << origin->FromClient->GetIdentity() << "': Unauthorized access."; | ||
return Empty; | ||
} | ||
|
||
if (!params->Contains("execution")) { | ||
Log(LogNotice, "ClusterEvents") | ||
<< "Discarding 'update executions API handler' message for checkable '" << checkable->GetName() | ||
|
@@ -1213,6 +1271,22 @@ Value ClusterEvents::ExecutedCommandAPIHandler(const MessageOrigin::Ptr& origin, | |
return Empty; | ||
} | ||
|
||
Endpoint::Ptr command_endpoint = Endpoint::GetByName(execution->Get("endpoint")); | ||
if (!command_endpoint) { | ||
Log(LogNotice, "ClusterEvents") | ||
<< "Discarding 'update executions API handler' message from '" << origin->FromClient->GetIdentity() | ||
<< "': Command endpoint does not exists."; | ||
|
||
return Empty; | ||
} | ||
|
||
if (origin->FromZone && !command_endpoint->GetZone()->IsChildOf(origin->FromZone)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only problem I see are messages from the own zone, but then -I guess- !!origin->FromZone wouldn’t be true. (JsonRpcConnection::MessageHandler()) |
||
Log(LogNotice, "ClusterEvents") | ||
<< "Discarding 'update executions API handler' message for checkable '" << checkable->GetName() | ||
<< "' from '" << origin->FromClient->GetIdentity() << "': Unauthorized access."; | ||
return Empty; | ||
} | ||
|
||
if (params->Contains("exit")) | ||
execution->Set("exit", params->Get("exit")); | ||
|
||
|
@@ -1303,7 +1377,7 @@ Value ClusterEvents::UpdateExecutionsAPIHandler(const MessageOrigin::Ptr& origin | |
updateMessage->Set("method", "event::UpdateExecutions"); | ||
updateMessage->Set("params", params); | ||
|
||
listener->RelayMessage(origin, Zone::GetLocalZone(), updateMessage, true); | ||
listener->RelayMessage(origin, checkable, updateMessage, true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LGTM There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... origin, checkable? Not even origin? Please explain. |
||
|
||
return Empty; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK this makes sense to me...