Skip to content
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

Conversation

mcodato
Copy link
Contributor

@mcodato mcodato commented Feb 8, 2021

Hi, this is our proposal for fixes #8616

Configuration for test

/etc/icinga2/conf.d/test.conf
Use this configuration on master, satellite and agent

object Host "satellite" {
    address = "127.0.0.1"
    check_command = "hostalive"
    zone = "satellite"
    vars.ls_dir = "/tmp/host"
    enable_active_checks = false
}

object Host "agent" {
    address = "127.0.0.1"
    check_command = "hostalive"
    zone = "satellite"
    vars.ls_dir = "/tmp/host"
    enable_active_checks = false
}

object Host "master" {
    address = "127.0.0.1"
    check_command = "hostalive"
}

object CheckCommand "custom_command" {
    command = [ "/usr/bin/ls", "$ls_dir$" ]
    zone = "global-commands"
}

Master

/etc/icinga2/zones.conf

object Zone "global-commands" {
    global = true
}

object Zone "global-templates" {
    global = true
}

object Zone "director-global" {
    global = true
}

object Endpoint "master" {
}

object Zone "master" {
    endpoints = [ "master" ]
}

object Endpoint "satellite" {
}

object Zone "satellite" {
    endpoints = [ "satellite" ]
    parent = "master"
}

object Endpoint "agent" {
    log_duration = 0s
}

object Zone "agent" {
    endpoints = [ "agent" ]
    parent = "satellite"
}

Satellite

/etc/icinga2/zones.conf

object Zone "global-commands" {
  global = true
}

object Zone "global-templates" {
    global = true
}

object Zone "director-global" {
    global = true
}

object Endpoint "master" {
    host = "127.0.0.1"
    port = "5665"
}

object Zone "master" {
    endpoints = [ "master" ]
}

object Endpoint "satellite" {
}

object Zone "satellite" {
    endpoints = [ "satellite" ]
    parent = "master"
}

object Endpoint "agent" {
    host = "127.0.0.1"
    port = "5663"
    log_duration = 0s
}

object Zone "agent" {
    endpoints = [ "agent" ]
    parent = "satellite"
}

Agent

/etc/icinga2/zones.conf

object Zone "global-commands" {
    global = true
}

object Endpoint "satellite" {
    host = "127.0.0.1"
    port = "5664"
}

object Zone "satellite" {
    endpoints = [ "satellite" ]
}

object Endpoint "agent" {
}

object Zone "agent" {
    endpoints = [ "agent" ]
    parent = "satellite"
}

object Zone "global-templates" {
    global = true
}

object Zone "director-global" {
    global = true
}

Test before the fix

Request

curl -k -sS -u root:admin -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/execute-command' -d '{"type":"Host", "host": "agent", "ttl":"60", "endpoint": "agent", "macros": { "ls_dir":"/tmp/foo" }, "command": "custom_command", "command_type": "CheckCommand" }'

Response

{"results":[{"checkable":"agent","code":202.0,"execution":"beca0a2c-a99d-4804-90a3-9bd7e142b302","status":"Accepted"}]}

Execution status

"beca0a2c-a99d-4804-90a3-9bd7e142b302" = {
    deadline = 1612800769.001815
    pending = true
}

Master logs

[2021-02-08 17:11:49 +0100] notice/ApiListener: New HTTP client
[2021-02-08 17:11:49 +0100] debug/HttpUtility: Request body: '{"type":"Host", "host": "agent", "ttl":"60", "endpoint": "agent", "macros": { "ls_dir":"/tmp/foo" }, "command": "custom_command", "command_type": "CheckCommand" }'
[2021-02-08 17:11:49 +0100] notice/ApiActionHandler: Running action execute-command
[2021-02-08 17:11:49 +0100] notice/ApiListener: Relaying 'event::UpdateExecutions' message
[2021-02-08 17:11:49 +0100] notice/ApiListener: Sending message 'event::UpdateExecutions' to 'satellite'
[2021-02-08 17:11:49 +0100] notice/ApiListener: Relaying 'event::ExecuteCommand' message
[2021-02-08 17:11:49 +0100] notice/ApiListener: Sending message 'event::ExecuteCommand' to 'satellite'
>> {"jsonrpc":"2.0","method":"event::UpdateExecutions","params":{"executions":{"beca0a2c-a99d-4804-90a3-9bd7e142b302":{"deadline":1612800769.001815,"pending":true}},"host":"agent"},"ts":1612800709.00188}
[2021-02-08 17:11:49 +0100] information/HttpServerConnection: Request: POST /v1/actions/execute-command (from [::1]:37268), user: root, agent: curl/7.71.1, status: Accepted).
>> {"jsonrpc":"2.0","method":"event::ExecuteCommand","params":{"command":"custom_command","command_type":"check_command","deadline":1612800769.001815,"endpoint":"agent","host":"agent","macros":{"ls_dir":"/tmp/foo"},"source":"beca0a2c-a99d-4804-90a3-9bd7e142b302"},"ts":1612800709.001983}
[2021-02-08 17:11:49 +0100] information/HttpServerConnection: HTTP client disconnected (from [::1]:37268)

Satellite logs

[2021-02-08 17:11:49 +0100] notice/JsonRpcConnection: Received 'event::UpdateExecutions' message from identity 'master'.
[2021-02-08 17:11:49 +0100] notice/ApiListener: Relaying 'event::UpdateExecutions' message
<< {"jsonrpc":"2.0","method":"event::ExecuteCommand","params":{"command":"custom_command","command_type":"check_command","deadline":1612800769.001815,"endpoint":"agent","host":"agent","macros":{"ls_dir":"/tmp/foo"},"source":"beca0a2c-a99d-4804-90a3-9bd7e142b302"},"ts":1612800709.001983}
[2021-02-08 17:11:49 +0100] notice/JsonRpcConnection: Received 'event::ExecuteCommand' message from identity 'master'.
[2021-02-08 17:11:49 +0100] notice/ApiListener: Relaying 'event::ExecuteCommand' message
[2021-02-08 17:11:49 +0100] notice/ApiListener: Sending message 'event::ExecuteCommand' to 'agent'
>> {"jsonrpc":"2.0","method":"event::ExecuteCommand","originZone":"master","params":{"command":"custom_command","command_type":"check_command","deadline":1612800769.001815,"endpoint":"agent","host":"agent","macros":{"ls_dir":"/tmp/foo"},"source":"beca0a2c-a99d-4804-90a3-9bd7e142b302"},"ts":1612800709.002931}
<< {"jsonrpc":"2.0","method":"event::ExecutedCommand","params":{"end":1612800709.006358,"execution":"beca0a2c-a99d-4804-90a3-9bd7e142b302","exit":2.0,"host":"agent","output":"/usr/bin/ls: cannot access '/tmp/foo': No such file or directory\n","start":1612800709.003923}}
[2021-02-08 17:11:49 +0100] notice/JsonRpcConnection: Received 'event::ExecutedCommand' message from identity 'agent'.
[2021-02-08 17:11:49 +0100] notice/ClusterEvents: Discarding 'update executions API handler' message for checkable 'agent' from 'agent': Unauthorized access.

Agent logs

[2021-02-08 17:11:49 +0100] notice/JsonRpcConnection: Received 'event::UpdateExecutions' message from identity 'master'.
[2021-02-08 17:11:49 +0100] notice/ApiListener: Relaying 'event::UpdateExecutions' message
<< {"jsonrpc":"2.0","method":"event::ExecuteCommand","params":{"command":"custom_command","command_type":"check_command","deadline":1612800769.001815,"endpoint":"agent","host":"agent","macros":{"ls_dir":"/tmp/foo"},"source":"beca0a2c-a99d-4804-90a3-9bd7e142b302"},"ts":1612800709.001983}
[2021-02-08 17:11:49 +0100] notice/JsonRpcConnection: Received 'event::ExecuteCommand' message from identity 'master'.
[2021-02-08 17:11:49 +0100] notice/ApiListener: Relaying 'event::ExecuteCommand' message
[2021-02-08 17:11:49 +0100] notice/ApiListener: Sending message 'event::ExecuteCommand' to 'agent'
>> {"jsonrpc":"2.0","method":"event::ExecuteCommand","originZone":"master","params":{"command":"custom_command","command_type":"check_command","deadline":1612800769.001815,"endpoint":"agent","host":"agent","macros":{"ls_dir":"/tmp/foo"},"source":"beca0a2c-a99d-4804-90a3-9bd7e142b302"},"ts":1612800709.002931}
<< {"jsonrpc":"2.0","method":"event::ExecutedCommand","params":{"end":1612800709.006358,"execution":"beca0a2c-a99d-4804-90a3-9bd7e142b302","exit":2.0,"host":"agent","output":"/usr/bin/ls: cannot access '/tmp/foo': No such file or directory\n","start":1612800709.003923}}
[2021-02-08 17:11:49 +0100] notice/JsonRpcConnection: Received 'event::ExecutedCommand' message from identity 'agent'.
[2021-02-08 17:11:49 +0100] notice/ClusterEvents: Discarding 'update executions API handler' message for checkable 'agent' from 'agent': Unauthorized access.

Test with the fix

Request

curl -k -sS -u root:admin -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/execute-command' -d '{"type":"Host", "host": "agent", "ttl":"60", "endpoint": "agent", "macros": { "ls_dir":"/tmp/foo" }, "command": "custom_command", "command_type": "CheckCommand" }'

Response

{"results":[{"checkable":"agent","code":202.0,"execution":"ce72a2a5-6237-41fe-a21b-a896d2fa1c5e","status":"Accepted"}]}

Exectuion status*

"ce72a2a5-6237-41fe-a21b-a896d2fa1c5e" = {
		deadline = 1612801142.086969
		end = 1612801082.090901
		exit = 2.000000
		output = "/usr/bin/ls: cannot access '/tmp/foo': No such file or directory\n"
		start = 1612801082.088762
	}

Master logs

[2021-02-08 17:18:02 +0100] notice/ApiListener: New HTTP client
[2021-02-08 17:18:02 +0100] debug/HttpUtility: Request body: '{"type":"Host", "host": "agent", "ttl":"60", "endpoint": "agent", "macros": { "ls_dir":"/tmp/foo" }, "command": "custom_command", "command_type": "CheckCommand" }'
[2021-02-08 17:18:02 +0100] notice/ApiActionHandler: Running action execute-command
[2021-02-08 17:18:02 +0100] notice/ApiListener: Relaying 'event::UpdateExecutions' message
[2021-02-08 17:18:02 +0100] notice/ApiListener: Sending message 'event::UpdateExecutions' to 'satellite'
[2021-02-08 17:18:02 +0100] notice/ApiListener: Relaying 'event::ExecuteCommand' message
[2021-02-08 17:18:02 +0100] notice/ApiListener: Sending message 'event::ExecuteCommand' to 'satellite'
[2021-02-08 17:18:02 +0100] information/HttpServerConnection: Request: POST /v1/actions/execute-command (from [::1]:38370), user: root, agent: curl/7.71.1, status: Accepted).
>> {"jsonrpc":"2.0","method":"event::UpdateExecutions","params":{"executions":{"ce72a2a5-6237-41fe-a21b-a896d2fa1c5e":{"deadline":1612801142.086969,"pending":true}},"host":"agent"},"ts":1612801082.087048}
>> {"jsonrpc":"2.0","method":"event::ExecuteCommand","params":{"command":"custom_command","command_type":"check_command","deadline":1612801142.086969,"endpoint":"agent","host":"agent","macros":{"ls_dir":"/tmp/foo"},"source":"ce72a2a5-6237-41fe-a21b-a896d2fa1c5e"},"ts":1612801082.087107}
[2021-02-08 17:18:02 +0100] information/HttpServerConnection: HTTP client disconnected (from [::1]:38370)
<< {"jsonrpc":"2.0","method":"event::UpdateExecutions","params":{"executions":{"ce72a2a5-6237-41fe-a21b-a896d2fa1c5e":{"deadline":1612801142.086969,"end":1612801082.090901,"exit":2.0,"output":"/usr/bin/ls: cannot access '/tmp/foo': No such file or directory\n","start":1612801082.088762}},"host":"agent"},"ts":1612801082.091564}
[2021-02-08 17:18:02 +0100] notice/JsonRpcConnection: Received 'event::UpdateExecutions' message from identity 'satellite'.
[2021-02-08 17:18:02 +0100] notice/ApiListener: Relaying 'event::UpdateExecutions' message

Satellite logs

<< {"jsonrpc":"2.0","method":"event::UpdateExecutions","params":{"executions":{"ce72a2a5-6237-41fe-a21b-a896d2fa1c5e":{"deadline":1612801142.086969,"pending":true}},"host":"agent"},"ts":1612801082.087048}
[2021-02-08 17:18:02 +0100] notice/JsonRpcConnection: Received 'event::UpdateExecutions' message from identity 'master'.
[2021-02-08 17:18:02 +0100] notice/ApiListener: Relaying 'event::UpdateExecutions' message
<< {"jsonrpc":"2.0","method":"event::ExecuteCommand","params":{"command":"custom_command","command_type":"check_command","deadline":1612801142.086969,"endpoint":"agent","host":"agent","macros":{"ls_dir":"/tmp/foo"},"source":"ce72a2a5-6237-41fe-a21b-a896d2fa1c5e"},"ts":1612801082.087107}
[2021-02-08 17:18:02 +0100] notice/JsonRpcConnection: Received 'event::ExecuteCommand' message from identity 'master'.
[2021-02-08 17:18:02 +0100] notice/ApiListener: Relaying 'event::ExecuteCommand' message
[2021-02-08 17:18:02 +0100] notice/ApiListener: Sending message 'event::ExecuteCommand' to 'agent'
>> {"jsonrpc":"2.0","method":"event::ExecuteCommand","originZone":"master","params":{"command":"custom_command","command_type":"check_command","deadline":1612801142.086969,"endpoint":"agent","host":"agent","macros":{"ls_dir":"/tmp/foo"},"source":"ce72a2a5-6237-41fe-a21b-a896d2fa1c5e"},"ts":1612801082.087914}
<< {"jsonrpc":"2.0","method":"event::ExecutedCommand","params":{"end":1612801082.090901,"execution":"ce72a2a5-6237-41fe-a21b-a896d2fa1c5e","exit":2.0,"host":"agent","output":"/usr/bin/ls: cannot access '/tmp/foo': No such file or directory\n","start":1612801082.088762}}
[2021-02-08 17:18:02 +0100] notice/JsonRpcConnection: Received 'event::ExecutedCommand' message from identity 'agent'.
[2021-02-08 17:18:02 +0100] notice/ApiListener: Relaying 'event::UpdateExecutions' message
[2021-02-08 17:18:02 +0100] notice/ApiListener: Sending message 'event::UpdateExecutions' to 'master'
>> {"jsonrpc":"2.0","method":"event::UpdateExecutions","params":{"executions":{"ce72a2a5-6237-41fe-a21b-a896d2fa1c5e":{"deadline":1612801142.086969,"end":1612801082.090901,"exit":2.0,"output":"/usr/bin/ls: cannot access '/tmp/foo': No such file or directory\n","start":1612801082.088762}},"host":"agent"},"ts":1612801082.091564}

Aagent logs

<< {"jsonrpc":"2.0","method":"event::ExecuteCommand","originZone":"master","params":{"command":"custom_command","command_type":"check_command","deadline":1612801142.086969,"endpoint":"agent","host":"agent","macros":{"ls_dir":"/tmp/foo"},"source":"ce72a2a5-6237-41fe-a21b-a896d2fa1c5e"},"ts":1612801082.087914}
[2021-02-08 17:18:02 +0100] notice/JsonRpcConnection: Received 'event::ExecuteCommand' message from identity 'satellite'.
[2021-02-08 17:18:02 +0100] notice/Process: Running command '/usr/bin/ls' '/tmp/foo': PID 1367365
[2021-02-08 17:18:02 +0100] notice/Process: PID 1367365 ('/usr/bin/ls' '/tmp/foo') terminated with exit code 2
[2021-02-08 17:18:02 +0100] notice/ApiListener: Sending message 'event::ExecutedCommand' to 'satellite'
>> {"jsonrpc":"2.0","method":"event::ExecutedCommand","params":{"end":1612801082.090901,"execution":"ce72a2a5-6237-41fe-a21b-a896d2fa1c5e","exit":2.0,"host":"agent","output":"/usr/bin/ls: cannot access '/tmp/foo': No such file or directory\n","start":1612801082.088762}}

@icinga-probot icinga-probot bot added this to the 2.13.0 milestone Feb 8, 2021
@Al2Klimov
Copy link
Member

Colleagues, any security objections?

Copy link
Contributor

@julianbrost julianbrost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me try to summarize to see if I understand correctly:

In order to schedule the execute a command on another node, this command has to be sent from a parent node to be accepted. This command references some config object which is then asynchronously updated with the result. However, this update performs a different permission check: the object must be accessible from the zone that sends the update. You can execute the command on any object though.

So a possible workaround should be to create a dummy host/service that is in the zone of the endpoint executing the command.

This PR would now introduce a new relationship between endpoint and host objects if they share the same name, allowing this update nonetheless. An alternative to this could probably be to store the command endpoint with the pending execution result and use this for update permission checks.

lib/icinga/clusterevents.cpp Outdated Show resolved Hide resolved
@mcodato
Copy link
Contributor Author

mcodato commented Feb 15, 2021

Hi @julianbrost, thanks for your feedback, we like the idea of storing the command endpoint in the execution object and we have implemented it. It can be tested with the same test above.

Copy link
Member

@Al2Klimov Al2Klimov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please squash your commits.

@mcodato mcodato force-pushed the bug/agent-cannot-update-executions-8616 branch from 3552c5d to 76c2e76 Compare February 15, 2021 15:56
lib/icinga/clusterevents.cpp Outdated Show resolved Hide resolved
@mcodato mcodato force-pushed the bug/agent-cannot-update-executions-8616 branch from 76c2e76 to 102f14f Compare February 17, 2021 08:33
@mcodato mcodato force-pushed the bug/agent-cannot-update-executions-8616 branch from 102f14f to 97b0d14 Compare February 17, 2021 11:16
@julianbrost
Copy link
Contributor

Seems like I've overlooked something when suggesting to change the permission check in this way: The permission check would be fine, but the object on which the execution is updated won't exist on intermediate satellites, so this won't help. This would be a general problem when decoupling the execution endpoint from the object's zone completely.

Endpoint names in the following examples refer to this cluster structure:

       m
      / \
     /   \
    /     \
  s-1     s-2
   |       |
   |       |
  a-1    s-2-1
           |
           |
          a-2

So in the most extreme case, the API would currently accept a command for the host object a-1 which is in zone s-1 (so a-1 is a command endpoint) to be executed on endpoint a-2. Executing this should be fine, however the result would never make it back as s-2 and s-2-1 don't know about the a-1 host object at all. The same would also happen if the object was in zone m or s-2, then s-2-1 still wouldn't be aware of it.

This could be fixed but would need major changes in how the results are returned (would have to be forwarded up the cluster without relying on any local objects). But I think this isn't even a use-case that you'd need but you only have this discrepancy in the object's zone because you're using the command endpoint feature.

So I see two possibilities how this could be fixed without completely overthrowing how the feature works:

  1. Restricting the endpoint parameter of the /v1/actions/execute-command API to those values, where we could currently execute and retrieve the result. That is the object's zone, all its parent zones and any direct child of a aforementioned zone. In this example, for an object in zone s-2-1, checks could be executed on m, s-2, s-2-1, a-2 and s-1 (but not a-1). For me this feels like a quite arbitrary restriction from a user's perspective.
  2. Removing the endpoint parameter from the /v1/actions/execute-command API and always using the command_endpoint, i.e. the current default. This would mean that the check is always executed where it would be if it was scheduled normally. This sounds like a reasonable restriction to me, but there's one caveat: if command_endpoint is only used for services but not the host itself, for example to perform a ping check from the satellite, executing on the host object would also execute the command on the satellite and you'd have to execute on a service object to execute on the actual host.

So please let me know what you think about this and which options would fit your needs so that we can figure out together how to proceed.

@julianbrost julianbrost modified the milestones: 2.13.0, 2.14.0 Jun 1, 2021
@mcodato mcodato force-pushed the bug/agent-cannot-update-executions-8616 branch 2 times, most recently from 4534b0c to 3c1835d Compare July 30, 2021 08:21
@mcodato
Copy link
Contributor Author

mcodato commented Jul 30, 2021

Hi @julianbrost sorry for the delay,
We believe the first proposal is the most appropriate for our use case.
We have implemented it, please let us know if this is correct

@julianbrost julianbrost removed the request for review from N-o-X January 3, 2022 15:36
Copy link
Contributor

@julianbrost julianbrost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @julianbrost sorry for the delay,

Well, I think I can't complain about that and have to say sorry for the delayed review myself.

lib/icinga/clusterevents.cpp Outdated Show resolved Hide resolved
lib/icinga/clusterevents.cpp Outdated Show resolved Hide resolved
lib/icinga/clusterevents.cpp Outdated Show resolved Hide resolved
lib/icinga/apiactions.cpp Outdated Show resolved Hide resolved
@julianbrost
Copy link
Contributor

@cla-bot check

@cla-bot cla-bot bot added the cla/signed label Jan 4, 2022
@mcodato mcodato force-pushed the bug/agent-cannot-update-executions-8616 branch from 3c1835d to 18bc625 Compare January 11, 2023 15:38
@mcodato mcodato requested review from julianbrost and Al2Klimov and removed request for Al2Klimov and julianbrost January 11, 2023 15:38
@mcodato mcodato requested review from julianbrost and removed request for Al2Klimov January 11, 2023 15:51
@Al2Klimov
Copy link
Member

C'mon Julian, you've even not resolved your threads not to mention not approved.

@Al2Klimov Al2Klimov removed their request for review January 19, 2023 12:28
lib/icinga/apiactions.cpp Outdated Show resolved Hide resolved
lib/icinga/clusterevents.cpp Outdated Show resolved Hide resolved
lib/icinga/clusterevents.cpp Outdated Show resolved Hide resolved
lib/icinga/clusterevents.cpp Outdated Show resolved Hide resolved
lib/icinga/apiactions.cpp Outdated Show resolved Hide resolved
@mcodato mcodato force-pushed the bug/agent-cannot-update-executions-8616 branch from 18bc625 to 0eb5fec Compare February 7, 2023 16:23
@mcodato mcodato force-pushed the bug/agent-cannot-update-executions-8616 branch from 0eb5fec to 730730c Compare February 8, 2023 07:33
Copy link
Member

@Al2Klimov Al2Klimov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Describe the big picture. Then vs. now. At best with diagrams. The can be hand drawn and photographed if you don't wanna deal with digital tools.

lib/icinga/apiactions.cpp Outdated Show resolved Hide resolved
lib/icinga/apiactions.cpp Outdated Show resolved Hide resolved
@Al2Klimov
Copy link
Member

Al2Klimov commented Mar 2, 2023

Also consider splitting your commit into multiple ones which successively lead from then to now. E.g. see commits here:

@mcodato mcodato force-pushed the bug/agent-cannot-update-executions-8616 branch from 730730c to 912fdb9 Compare March 2, 2023 16:51
lib/icinga/clusterevents.cpp Outdated Show resolved Hide resolved
lib/icinga/apiactions.cpp Outdated Show resolved Hide resolved
@julianbrost julianbrost dismissed Al2Klimov’s stale review April 11, 2023 13:57

There's already enough information in the description and comment history.

return Empty;
}

if (origin->FromZone && !origin->FromZone->CanAccessObject(command_endpoint->GetZone())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apropos, I consider zoneA->CanAccessObject(zoneB) kinda confusing. Doesn’t this -according to CanAccessObject() code- query for a child/parent relationship?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of
origin->FromZone->CanAccessObject(command_endpoint->GetZone())
is it better to use
command_endpoint->GetZone()->isChildOf(origin->FromZone) ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is what you wanna check for, yes. IMAO it's more descriptive. But let's Julian cross-check first..

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the return path for the response. The request was sent to the endpoint command_endpoint so this is supposed to check whether the response is coming from (directly or indirectly) that endpoint. That should be checked by both variants but with IsChildOf() that might be a bit more obvious (especially given that CanAccessObject() would also do GetZone() internally, but that wouldn't do the same, greetings to #8740).

julianbrost
julianbrost previously approved these changes Apr 13, 2023
Copy link
Contributor

@julianbrost julianbrost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM now.

@Al2Klimov Do you want to have another look at this before merging? The change is basically storing the execution endpoint in the slot for the result (where the deadline is already stored for example) and then changes to the message forwarding and related permission checks to actually make it work.

@Al2Klimov Al2Klimov self-requested a review April 13, 2023 10:40
"Zone '" + endpointZone->GetName() + "' cannot access checkable '" + checkable->GetName() + "'."
);
}

Copy link
Member

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...

<< ": Endpoint " << params->Get("endpoint") << " does not exist";
return Empty;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far so good...

@@ -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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

return Empty;
}

if (origin->FromZone && !command_endpoint->GetZone()->IsChildOf(origin->FromZone)) {
Copy link
Member

Choose a reason for hiding this comment

The 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())

executedMessage->Set("method", "event::ExecutedCommand");
executedMessage->Set("params", executedParams);

listener->RelayMessage(nullptr, nullptr, executedMessage, true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh? nullptr, nullptr? Not...

Copy link
Contributor

Choose a reason for hiding this comment

The 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 event::ExecutedCommand message already used the same ones.

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I tested, I agree with Julian, using origin, checkable the message is not sent back and the execution remains in the pending state

	"a9086343-4da7-44ae-8fd6-5f16641cbd5e" = {
		deadline = 1681388550.850034
		endpoint = "agent"
		pending = true
	}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. 😅 🐘

@@ -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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... origin, checkable? Not even origin? Please explain.

Host::Ptr host = Host::GetByName(params->Get("host"));
if (!host) {
Log(LogWarning, "ClusterEvents")
<< "Discarding 'execute command' message " << executionUuid
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit of indentation...

checkableName += "!" + params->Get("service");

Log(LogWarning, "ClusterEvents")
<< "Discarding 'execute command' message " << executionUuid
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... wouldn’t hurt.

Copy link
Member

@Al2Klimov Al2Klimov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be clear: I asked you for splitting commits by things of what you changed since master (which you did by now). IMAO this doesn’t contradict my previous squash request which targeted fixes of the changeset itself. Apropos: Please squash not everything, but just the indentation fixes into the respective commit(s?) the misindentation comes from. So you get two commits again, but both of them w/o misindentation – and you're finally (😅) done.

…but checkable has command_endpoint specified
@mcodato mcodato force-pushed the bug/agent-cannot-update-executions-8616 branch from dd114c4 to c5c1792 Compare April 13, 2023 12:44
Copy link
Member

@Al2Klimov Al2Klimov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make it so!

Copy link
Contributor

@julianbrost julianbrost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only whitespace changes since my last review, so that one is pretty much still valid.

@julianbrost julianbrost merged commit 8228fae into Icinga:master Apr 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ExecuteCommand API - Agent cannot update executions
4 participants