Skip to content

Commit

Permalink
Merge pull request #1385 from it-novum/ITC-1911
Browse files Browse the repository at this point in the history
ITC-1911 host child status incorrect if monitored from different system
  • Loading branch information
nook24 authored Jul 29, 2022
2 parents 5f1bcca + 1dddb13 commit b56b7bb
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 7 deletions.
5 changes: 4 additions & 1 deletion UPDATE.sh
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,10 @@ oitc agent --generate-server-ca
#echo "Apply strict checking of host group assignments by container permissions"
#oitc HostgroupContainerPermissions

# ITC-1911
echo "Cleanup for invalid parent hosts on satellite instance"
oitc ParentHostsVisibilityCleaning

NORESTART=false
NOSYSTEMFILES=false
for i in "$@"; do
Expand Down Expand Up @@ -531,4 +535,3 @@ chown www-data:www-data /opt/openitc/frontend/tmp
chown nagios:nagios -R /opt/openitc/frontend/tmp/nagios
chmod u+s /opt/openitc/nagios/libexec/check_icmp
chmod u+s /opt/openitc/nagios/libexec/check_dhcp

123 changes: 123 additions & 0 deletions src/Command/ParentHostsVisibilityCleaningCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?php
declare(strict_types=1);

namespace App\Command;

use App\Model\Entity\Changelog;
use App\Model\Table\ChangelogsTable;
use App\Model\Table\HostsTable;
use App\Model\Table\HosttemplatesTable;
use Cake\Command\Command;
use Cake\Console\Arguments;
use Cake\Console\ConsoleIo;
use Cake\Console\ConsoleOptionParser;
use Cake\ORM\TableRegistry;
use Cake\Utility\Hash;
use itnovum\openITCOCKPIT\Core\Comparison\HostComparisonForSave;
use itnovum\openITCOCKPIT\Core\HostConditions;
use itnovum\openITCOCKPIT\Core\Merger\HostMergerForView;

/**
* ParentHostsVisibilityCleaning command.
*/
class ParentHostsVisibilityCleaningCommand extends Command {
/**
* Hook method for defining this command's option parser.
*
* @see https://book.cakephp.org/4/en/console-commands/commands.html#defining-arguments-and-options
* @param \Cake\Console\ConsoleOptionParser $parser The parser to be defined
* @return \Cake\Console\ConsoleOptionParser The built parser.
*/
public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser {
$parser = parent::buildOptionParser($parser);
return $parser;
}

/**
* Implement this method with your command's logic.
*
* @param \Cake\Console\Arguments $args The command arguments.
* @param \Cake\Console\ConsoleIo $io The console io
* @return null|void|int The exit code or null for success
*/
public function execute(Arguments $args, ConsoleIo $io) {
$lockfile = '/opt/openitc/var/parent_hosts_cleaning.lock';

if (file_exists($lockfile)) {
$io->success('Update has already been done');
exit(0);
}


/** @var HostsTable $HostsTable */
$HostsTable = TableRegistry::getTableLocator()->get('Hosts');
/** @var HosttemplatesTable $HosttemplatesTable */
$HosttemplatesTable = TableRegistry::getTableLocator()->get('Hosttemplates');
/** @var ChangelogsTable $ChangelogsTable */
$ChangelogsTable = TableRegistry::getTableLocator()->get('Changelogs');


$hosts = $HostsTable->getHostsAsList();
$HostConditions = new HostConditions();
foreach ($hosts as $hostId => $hostName) {
$host = $HostsTable->getHostForEdit($hostId);
if ($host['Host']['satellite_id'] === 0 || empty($host['Host']['parenthosts']['_ids'])) {
continue;
}
$HostConditions->setHostIds($host['Host']['parenthosts']['_ids']);
$parentHosts = $HostsTable->getHostsByHostConditions($HostConditions);
$parenHostFilteredIds = Hash::extract($parentHosts, '{n}.Host[satellite_id=' . $host['Host']['satellite_id'] . '].id');

$parentHostsDifference = array_diff($host['Host']['parenthosts']['_ids'], $parenHostFilteredIds);
if (!empty($parentHostsDifference)) {
$io->info('Hostname: ' . $host['Host']['name']);

$hosttemplate = $HosttemplatesTable->getHosttemplateForDiff($host['Host']['hosttemplate_id']);
//update host
$HostMergerForView = new HostMergerForView($host, $hosttemplate);
$mergedHost = $HostMergerForView->getDataForView();
$hostForChangelog = $mergedHost;

$mergedHost['Host']['parenthosts']['_ids'] = $parenHostFilteredIds;
$HostComparisonForSave = new HostComparisonForSave($mergedHost, $hosttemplate);
$dataForSave = $HostComparisonForSave->getDataForSaveForAllFields();
//Add required fields for validation
$dataForSave['hosttemplate_flap_detection_enabled'] = $hosttemplate['Hosttemplate']['flap_detection_enabled'];
$dataForSave['hosttemplate_flap_detection_on_up'] = $hosttemplate['Hosttemplate']['flap_detection_on_up'];
$dataForSave['hosttemplate_flap_detection_on_down'] = $hosttemplate['Hosttemplate']['flap_detection_on_down'];
$dataForSave['hosttemplate_flap_detection_on_unreachable'] = $hosttemplate['Hosttemplate']['flap_detection_on_unreachable'];


$hostEntity = $HostsTable->get($host['Host']['id']);
$hostEntity = $HostsTable->patchEntity($hostEntity, $dataForSave);

$HostsTable->save($hostEntity);
//No errors
if (!$hostEntity->hasErrors()) {
$io->error('Old parent hosts: ' . json_encode($host['Host']['parenthosts']['_ids']));
$io->success('New parent hosts: ' . json_encode($parenHostFilteredIds));

$changelog_data = $ChangelogsTable->parseDataForChangelog(
'edit',
'hosts',
$hostEntity->get('id'),
OBJECT_HOST,
$hostEntity->get('container_id'),
0,
$hostEntity->get('name'),
array_merge($HostsTable->resolveDataForChangelog($mergedHost), $mergedHost),
array_merge($HostsTable->resolveDataForChangelog($hostForChangelog), $hostForChangelog)
);
if ($changelog_data) {
/** @var Changelog $changelogEntry */
$changelogEntry = $ChangelogsTable->newEntity($changelog_data);
$ChangelogsTable->save($changelogEntry);
}
}
}
$io->out('');

}
file_put_contents($lockfile, 'Parent hosts fix was running at: ' . date('Y-m-d H:i:s'));
}
}
19 changes: 17 additions & 2 deletions src/Controller/HostsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -1670,7 +1670,9 @@ public function copy($id = null) {
'tags',
'active_checks_enabled',
'satellite_id',
'notifications_enabled'
'notifications_enabled',
'freshness_checks_enabled',
'freshness_threshold'
]
);
/** @var \App\Model\Entity\Hosttemplate $hosttemplate */
Expand All @@ -1695,7 +1697,9 @@ public function copy($id = null) {
$containerIds[] = $container->get('id');
}
foreach ($sourceHost->get('parenthosts') as $parenthost) {
$parenthostsIds[] = $parenthost->get('id');
if ($sourceHost->get('satellite_id') === 0 || $sourceHost->get('satellite_id') === $parenthost->get('satellite_id')) {
$parenthostsIds[] = $parenthost->get('id');
}
}
foreach ($sourceHost->get('contacts') as $contact) {
$contactsIds[] = $contact->get('id');
Expand Down Expand Up @@ -2003,6 +2007,15 @@ public function browser($idOrUuid = null) {
}

$host = $HostsTable->getHostForBrowser($id);
if (!empty($host['parenthosts']) && $host['satellite_id'] > 0) {
$parentHostsFiltered = [];
foreach ($host['parenthosts'] as $parentHost) {
if ($parentHost['satellite_id'] === 0 || $parentHost['satellite_id'] === $host['satellite_id']) {
$parentHostsFiltered[] = $parentHost;
}
}
$host['parenthosts'] = $parentHostsFiltered;
}

//Check permissions
$containerIdsToCheck = Hash::extract($host, 'hosts_to_containers_sharing.{n}.id');
Expand Down Expand Up @@ -3067,6 +3080,7 @@ public function loadParentHostsByString() {
$selected = $this->request->getQuery('selected');
$hostId = $this->request->getQuery('hostId');
$containerId = $this->request->getQuery('containerId');
$satelliteId = $this->request->getQuery('satellite_id');
$containerIds = [ROOT_CONTAINER, $containerId];
if ($containerId == ROOT_CONTAINER) {
/** @var $ContainersTable ContainersTable */
Expand All @@ -3091,6 +3105,7 @@ public function loadParentHostsByString() {
'Hosts.id IN' => $hostId
]);
}
$HostCondition->setSatelliteId($satelliteId);
$hosts = Api::makeItJavaScriptAble(
$HostsTable->getHostsForAngular($HostCondition, $selected)
);
Expand Down
7 changes: 6 additions & 1 deletion src/Model/Table/HostsTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -1877,6 +1877,10 @@ public function getHostsForAngular(HostConditions $HostConditions, $selected = [
if ($HostConditions->includeDisabled() === false) {
$where['Hosts.disabled'] = 0;
}
$satelliteId = $HostConditions->getSatelliteId();
if ($satelliteId !== null) {
$where['Hosts.satellite_id'] = $satelliteId;
}
if ($HostConditions->hasNotConditions()) {
if (!empty($where['NOT'])) {
$where['NOT'] = array_merge($where['NOT'], $HostConditions->getNotConditions());
Expand Down Expand Up @@ -3137,7 +3141,8 @@ function (Query $q) {
function (Query $q) {
return $q->enableAutoFields(false)->select([
'id',
'name'
'name',
'satellite_id'
]);
},
'Hostcommandargumentvalues' => [
Expand Down
16 changes: 15 additions & 1 deletion webroot/js/scripts/controllers/Hosts/HostsAddController.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,8 @@ angular.module('openITCOCKPIT')
'angular': true,
'filter[Hosts.name]': searchString,
'selected[]': $scope.post.Host.parenthosts._ids,
'containerId': containerId
'containerId': containerId,
'satellite_id': ($scope.post.Host.satellite_id > 0)?$scope.post.Host.satellite_id :null
}
}).then(function(result){
$scope.parenthosts = result.data.hosts;
Expand Down Expand Up @@ -375,6 +376,13 @@ angular.module('openITCOCKPIT')
};

$scope.submit = function(redirectState){

//clean up parent host -> remove not visible ids
$scope.post.Host.parenthosts._ids = _.intersection(
_.map($scope.parenthosts, 'key'),
$scope.post.Host.parenthosts._ids
);

//clean up host and host templates -> remove not visible ids
$scope.post.Host.hostgroups._ids = _.intersection(
_.map($scope.hostgroups, 'key'),
Expand Down Expand Up @@ -522,4 +530,10 @@ angular.module('openITCOCKPIT')
}
}, true);

$scope.$watch('post.Host.satellite_id', function(){
if($scope.init){
return;
}
$scope.loadParentHosts('');
}, true);
});
17 changes: 15 additions & 2 deletions webroot/js/scripts/controllers/Hosts/HostsEditController.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ angular.module('openITCOCKPIT')
'filter[Hosts.name]': searchString,
'selected[]': $scope.post.Host.parenthosts._ids,
'containerId': containerId,
'hostId': $scope.id
'hostId': $scope.id,
'satellite_id': ($scope.post.Host.satellite_id > 0)?$scope.post.Host.satellite_id :null
}
}).then(function(result){
$scope.parenthosts = result.data.hosts;
Expand Down Expand Up @@ -343,13 +344,19 @@ angular.module('openITCOCKPIT')
};

$scope.submit = function(redirectState){

//clean up parent host -> remove not visible ids
$scope.post.Host.parenthosts._ids = _.intersection(
_.map($scope.parenthosts, 'key'),
$scope.post.Host.parenthosts._ids
);

//clean up host and host templates -> remove not visible ids
$scope.post.Host.hostgroups._ids = _.intersection(
_.map($scope.hostgroups, 'key'),
$scope.post.Host.hostgroups._ids
);


$http.post("/hosts/edit/" + $scope.id + ".json?angular=true",
$scope.post
).then(function(result){
Expand Down Expand Up @@ -510,4 +517,10 @@ angular.module('openITCOCKPIT')
}
}
});
$scope.$watch('post.Host.satellite_id', function(){
if($scope.init){
return;
}
$scope.loadParentHosts('');
}, true);
});

0 comments on commit b56b7bb

Please sign in to comment.