Skip to content

Commit

Permalink
Merge development into ITC-2974
Browse files Browse the repository at this point in the history
  • Loading branch information
nook24 committed Jul 7, 2023
2 parents a9b033e + 7a3f894 commit 8ace349
Show file tree
Hide file tree
Showing 79 changed files with 3,129 additions and 133 deletions.
59 changes: 59 additions & 0 deletions config/Migrations/20230704135047_UniqueIndexForUsergroups.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
// Copyright (C) <2015> <it-novum GmbH>
//
// This file is dual licensed
//
// 1.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// 2.
// If you purchased an openITCOCKPIT Enterprise Edition you can use this file
// under the terms of the openITCOCKPIT Enterprise Edition license agreement.
// License agreement and license key will be shipped with the order
// confirmation.

declare(strict_types=1);

use Migrations\AbstractMigration;

/**
* Class UniqueIndexForUsergroups
*
* Created via:
* oitc migrations create UniqueIndexForUsergroups
*
* Run migration:
* oitc migrations migrate
*
*/
class UniqueIndexForUsergroups extends AbstractMigration {
/**
* Change Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
* @return void
*/
public function change(): void {
if ($this->hasTable('usergroups')) {
$this->table('usergroups')
->addIndex(
[
'name',
],
['unique' => true]
)
->update();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
use Cake\Http\Exception\NotFoundException;
use Cake\Log\Log;
use Cake\ORM\TableRegistry;
use GrafanaModule\Model\Entity\GrafanaUserdashboardMetric;
use GrafanaModule\Model\Entity\GrafanaUserdashboardPanel;
use GrafanaModule\Model\Table\GrafanaConfigurationsTable;
use GrafanaModule\Model\Table\GrafanaUserdashboardMetricsTable;
use GrafanaModule\Model\Table\GrafanaUserdashboardPanelsTable;
Expand Down Expand Up @@ -402,6 +404,127 @@ public function delete($id) {
$this->viewBuilder()->setOption('serialize', ['success', 'message']);
}

/**
* @param int|null $id
*/
public function copy($id = null) {
if (!$this->isAngularJsRequest()) {
//Only ship HTML Template
return;
}

/** @var GrafanaUserdashboardsTable $GrafanaUserdashboardsTable */
$GrafanaUserdashboardsTable = TableRegistry::getTableLocator()->get('GrafanaModule.GrafanaUserdashboards');
/** @var GrafanaUserdashboardPanelsTable $GrafanaUserdashboardPanelsTable */
$GrafanaUserdashboardPanelsTable = TableRegistry::getTableLocator()->get('GrafanaModule.GrafanaUserdashboardPanels');
/** @var GrafanaUserdashboardMetricsTable $GrafanaUserdashboardMetricsTable */
$GrafanaUserdashboardMetricsTable = TableRegistry::getTableLocator()->get('GrafanaModule.GrafanaUserdashboardMetrics');

$MY_RIGHTS = $this->MY_RIGHTS;
if ($this->hasRootPrivileges) {
$MY_RIGHTS = [];
}

if ($this->request->is('get')) {
$dashboards = $GrafanaUserdashboardsTable->getGrafanaUserdashboardsForCopy(func_get_args(), $MY_RIGHTS);
$this->set('dashboards', $dashboards);
$this->viewBuilder()->setOption('serialize', ['dashboards']);
return;
}

$hasErrors = false;

if ($this->request->is('post')) {
$postData = $this->request->getData('data', []);

foreach ($postData as $index => $dashboardData) {
if (!isset($dashboardData['Dashboard']['id'])) {
//Create/clone Grafana User Dashboard
$sourceId = $dashboardData['Source']['id'];
$sourceDashboard = $GrafanaUserdashboardsTable->getSourceGrafanaUserdashboardForCopy($sourceId, $MY_RIGHTS);

$newDashboardData = $sourceDashboard;
$newDashboardData['name'] = $dashboardData['Dashboard']['name'];

$newDashboardEntity = $GrafanaUserdashboardsTable->newEntity($newDashboardData);
}

$action = 'copy';
if (isset($dashboardData['Dashboard']['id'])) {
//Update existing Grafana Userdashboard
//This happens, if a user copy multiple dashboards, and one run into an validation error
//All dashboards without validation errors got already saved to the database
$newDashboardEntity = $GrafanaUserdashboardsTable->get($dashboardData['Dashboard']['id']);
$newDashboardEntity->setAccess('id', false);
$newDashboardEntity->setAccess('container_id', false);
$newDashboardEntity->set('name', $dashboardData['Dashboard']['name']);
$action = 'edit';
}
$GrafanaUserdashboardsTable->save($newDashboardEntity);

$postData[$index]['Error'] = [];
if ($newDashboardEntity->hasErrors()) {
$hasErrors = true;
$postData[$index]['Error'] = $newDashboardEntity->getErrors();
} else {
//No errors

// Due to Grafana User Dashboards are a bit special, we need to create the Dashboard first,
// than add panels and in the last step we can add metrics to the panels :/
// Therefor we only do this for new copies, not for an update (due to validation errors)
if ($action === 'copy') {
$sourcePanels = $GrafanaUserdashboardPanelsTable->getPanelsByUserdashboardIdForCopy($dashboardData['Source']['id']);
if (!empty($sourcePanels)) {
foreach ($sourcePanels as $sourcePanel) {
/** @var GrafanaUserdashboardPanel $sourcePanel */
$newPanelEntity = $GrafanaUserdashboardPanelsTable->newEntity([
'userdashboard_id' => $newDashboardEntity->get('id'),
'row' => $sourcePanel->row,
'unit' => $sourcePanel->unit,
'title' => $sourcePanel->title,
'visualization_type' => $sourcePanel->visualization_type,
'stacking_mode' => $sourcePanel->stacking_mode
]);

$GrafanaUserdashboardPanelsTable->save($newPanelEntity);
if (!$newPanelEntity->hasErrors()) {
// Copy metrics form source dashboard/panel into the new panel
$sourceMetrics = $GrafanaUserdashboardMetricsTable->getMetricsByPanelIdForCopy($sourcePanel->get('id'));
if (!empty($sourceMetrics)) {
foreach ($sourceMetrics as $sourceMetric) {
/** @var GrafanaUserdashboardMetric $sourceMetric */
$newMetricEntity = $GrafanaUserdashboardMetricsTable->newEntity([
'panel_id' => $newPanelEntity->get('id'),
'metric' => $sourceMetric->metric,
'host_id' => $sourceMetric->host_id,
'service_id' => $sourceMetric->service_id,
'color' => $sourceMetric->color
]);
$GrafanaUserdashboardMetricsTable->save($newMetricEntity);
}
}
}

}
}
}

$postData[$index]['Dashboard']['id'] = $newDashboardEntity->get('id');
}
}
}

if ($hasErrors) {
$this->response = $this->response->withStatus(400);
}
$this->set('result', $postData);
$this->viewBuilder()->setOption('serialize', ['result']);
}

/****************************
* AJAX METHODS *
****************************/

/**
* @throws \Exception
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,17 @@ public function existsById($id) {
return $this->exists(['GrafanaUserdashboardMetrics.id' => $id]);
}

/**
* @param int $panelId
* @return \Cake\Datasource\ResultSetInterface
*/
public function getMetricsByPanelIdForCopy(int $panelId) {
$result = $this->find()
->where([
'GrafanaUserdashboardMetrics.panel_id' => $panelId
])
->all();
return $result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,18 @@ public function getNextRow($dashboardId) {
return $result->get('row') + 1;
}

/**
* @param int $dashboardId
* @return \Cake\Datasource\ResultSetInterface
*/
public function getPanelsByUserdashboardIdForCopy(int $dashboardId){
$result = $this->find()
->where([
'GrafanaUserdashboardPanels.userdashboard_id' => $dashboardId
])
->all();

return $result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -366,11 +366,66 @@ public function getGrafanaUserdashboardsWithPanelsAndMetricsById($id) {
return $query->first();
}

/**
* @param array $ids
* @param array $MY_RIGHTS
* @return array
*/
public function getGrafanaUserdashboardsForCopy($ids = [], array $MY_RIGHTS = []) {
$query = $this->find()
->select([
'GrafanaUserdashboards.id',
'GrafanaUserdashboards.name'
])
->where(['GrafanaUserdashboards.id IN' => $ids])
->order(['GrafanaUserdashboards.id' => 'asc']);

if (!empty($MY_RIGHTS)) {
$query->andWhere([
'GrafanaUserdashboards.container_id IN' => $MY_RIGHTS
]);
}

$query->disableHydration()
->all();

return $this->emptyArrayIfNull($query->toArray());
}

/**
* @param $sourceAutomapId
* @param array $MY_RIGHTS
* @return array
*/
public function getSourceGrafanaUserdashboardForCopy($sourceAutomapId, array $MY_RIGHTS = []) {
$query = $this->find()
->where(['GrafanaUserdashboards.id' => $sourceAutomapId]);
if (!empty($MY_RIGHTS)) {
$query->andWhere([
'GrafanaUserdashboards.container_id IN' => $MY_RIGHTS
]);
}

$result = $query->firstOrFail();
$dbResult = $this->emptyArrayIfNull($result->toArray());
if (empty($dbResult)) {
return [];
}

// Remove IDs of source elements
$dashboard = [
'container_id' => $dbResult['container_id'],
'configuration_id' => $dbResult['configuration_id']
];

return $dashboard;
}

/**
* @param int $containerId
* @return array
*/
public function getOrphanedGrafanaUserdashboardsByContainerId(int $containerId){
public function getOrphanedGrafanaUserdashboardsByContainerId(int $containerId) {
$query = $this->find()
->where(['container_id' => $containerId]);
$result = $query->all();
Expand Down
Loading

0 comments on commit 8ace349

Please sign in to comment.