Proxxgers + ZBX hosts Sync
This commit is contained in:
parent
84ef42382a
commit
2f4f917032
@ -2,10 +2,35 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Host;
|
||||
use App\Services\ZabbixService;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class HostController extends BaseController
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('hosts.index');
|
||||
}
|
||||
|
||||
public function sync()
|
||||
{
|
||||
$zabbix = new ZabbixService("https://zabbix.itego.cz");
|
||||
$zabbix->connect("spaninger", "*");
|
||||
|
||||
foreach ( $zabbix->maintenances([ "selectTimeperiods" => "extend" ]) as $maintennace ) {
|
||||
if(!Carbon::createFromTimestamp($maintennace['active_till'])->isPast()){
|
||||
dd(Carbon::createFromTimestamp($maintennace['active_till']));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($zabbix->hosts() as $host) {
|
||||
Host::updateOrCreate([
|
||||
"hostname" => $host['host'],
|
||||
], [
|
||||
"display_name" => $host['name'],
|
||||
]);
|
||||
}
|
||||
return redirect()->back();
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\MaintenanceHistory;
|
||||
use App\Services\ZabbixService;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
@ -31,6 +32,7 @@ public function plannedDetail(MaintenanceHistory $maintenance_history)
|
||||
|
||||
public function plannedDetailPut(Request $request, MaintenanceHistory $maintenance_history)
|
||||
{
|
||||
|
||||
if (!empty($maintenance_history->finished_at)) {
|
||||
abort(404);
|
||||
}
|
||||
|
@ -34,8 +34,14 @@ public function handle(): void
|
||||
$maintenances = Maintenance::all();
|
||||
foreach ($maintenances as $maintenance) {
|
||||
$cron = new CronCronExpression($maintenance->schedule);
|
||||
$nextRunTime = Carbon::createFromTimestamp($cron->getNext());
|
||||
|
||||
if(MaintenanceHistory::where('hash', md5($maintenance->id . $nextRunTime))->first() === null){
|
||||
continue;
|
||||
};
|
||||
|
||||
$maintenancePlanned = $maintenance->history()->create([
|
||||
'start_at' => Carbon::createFromTimestamp($cron->getNext()),
|
||||
'start_at' => $nextRunTime,
|
||||
'guestor_id' => $maintenance->guestor_id,
|
||||
]);
|
||||
$maintenancePlanned->refresh();
|
||||
|
@ -2,6 +2,7 @@
|
||||
namespace App\Livewire\Host;
|
||||
|
||||
use App\Models\Host;
|
||||
use App\Services\ZabbixService;
|
||||
use SteelAnts\DataTable\Livewire\DataTableComponent;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
@ -12,6 +13,9 @@ class DataTable extends DataTableComponent
|
||||
'closeModal' => '$refresh',
|
||||
];
|
||||
|
||||
public bool $searchable = true;
|
||||
public array $searchableColumns = ['display_name', 'hostname'];
|
||||
|
||||
public function query(): Builder
|
||||
{
|
||||
return Host::query();
|
||||
@ -20,6 +24,7 @@ public function query(): Builder
|
||||
public function headers(): array
|
||||
{
|
||||
return [
|
||||
'display_name' => 'display_name',
|
||||
'hostname' => 'hostname',
|
||||
];
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ class Host extends Model
|
||||
|
||||
protected $fillable = [
|
||||
'hostname',
|
||||
'display_name',
|
||||
];
|
||||
|
||||
public function tasks()
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Observers\MaintenanceHistoryObserver;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
@ -16,6 +17,12 @@ class MaintenanceHistory extends Model
|
||||
'guestor_id',
|
||||
];
|
||||
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
MaintenanceHistory::observe(MaintenanceHistoryObserver::class);
|
||||
}
|
||||
|
||||
public function maintenance()
|
||||
{
|
||||
return $this->BelongsTo(Maintenance::class);
|
||||
|
18
app/Observers/MaintenanceHistoryObserver.php
Normal file
18
app/Observers/MaintenanceHistoryObserver.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Observers;
|
||||
|
||||
use App\Models\MaintenanceHistory;
|
||||
|
||||
class MaintenanceHistoryObserver
|
||||
{
|
||||
public function creating(MaintenanceHistory $maintenanceHistory): void
|
||||
{
|
||||
$maintenanceHistory->hash = md5($maintenanceHistory->maintenance_id . $maintenanceHistory->start_at);
|
||||
}
|
||||
|
||||
public function updating(MaintenanceHistory $maintenanceHistory): void
|
||||
{
|
||||
$maintenanceHistory->hash = md5($maintenanceHistory->maintenance_id . $maintenanceHistory->start_at);
|
||||
}
|
||||
}
|
130
app/Services/ZabbixService.php
Normal file
130
app/Services/ZabbixService.php
Normal file
@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class ZabbixService
|
||||
{
|
||||
public string $token = "";
|
||||
public string $url = "";
|
||||
public int $id = 1;
|
||||
|
||||
function __construct($url) {
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
public function connect( $username, $password)
|
||||
{
|
||||
$response = Http::withoutVerifying()->post($this->url . "/api_jsonrpc.php", [
|
||||
"jsonrpc" => "2.0",
|
||||
"method" => "user.login",
|
||||
"params" => [
|
||||
"username" => $username,
|
||||
"password" => $password,
|
||||
],
|
||||
"id" => $this->id,
|
||||
"auth" => null,
|
||||
]);
|
||||
|
||||
if (!$response->successful()) {
|
||||
throw new Exception("Unable To Authenticated", 1);
|
||||
}
|
||||
|
||||
$responseObject = $response->json();
|
||||
if (isset($responseObject['error'])) {
|
||||
throw new Exception($responseObject['error']['data'], $responseObject['error']['code']);
|
||||
}
|
||||
|
||||
$this->token = $response['result'];
|
||||
$this->id++;
|
||||
}
|
||||
|
||||
public function hosts($params = [])
|
||||
{
|
||||
if (empty($this->token)) {
|
||||
throw new Exception("you need to connect first", 1);
|
||||
}
|
||||
|
||||
$response = Http::withoutVerifying()->post($this->url . "/api_jsonrpc.php", [
|
||||
"jsonrpc" => "2.0",
|
||||
"method" => "host.get",
|
||||
"params" => $params,
|
||||
"id" => $this->id,
|
||||
"auth" => $this->token,
|
||||
]);
|
||||
|
||||
if (!$response->successful()) {
|
||||
throw new Exception("Unable To Request", 1);
|
||||
}
|
||||
|
||||
$responseObject = $response->json();
|
||||
if (isset($responseObject['error'])) {
|
||||
throw new Exception($responseObject['error']['data'], $responseObject['error']['code']);
|
||||
}
|
||||
|
||||
$this->id++;
|
||||
return collect($responseObject["result"]);
|
||||
}
|
||||
|
||||
public function hostGroups($params = [])
|
||||
{
|
||||
if (empty($this->token)) {
|
||||
throw new Exception("you need to connect first", 1);
|
||||
}
|
||||
|
||||
$response = Http::withoutVerifying()->post($this->url . "/api_jsonrpc.php", [
|
||||
"jsonrpc" => "2.0",
|
||||
"method" => "hostgroup.get",
|
||||
"params" => $params,
|
||||
"id" => $this->id,
|
||||
"auth" => $this->token,
|
||||
]);
|
||||
|
||||
if (!$response->successful()) {
|
||||
throw new Exception("Unable To Request", 1);
|
||||
}
|
||||
|
||||
$responseObject = $response->json();
|
||||
if (isset($responseObject['error'])) {
|
||||
throw new Exception($responseObject['error']['data'], $responseObject['error']['code']);
|
||||
}
|
||||
|
||||
$this->id++;
|
||||
return collect($responseObject["result"]);
|
||||
}
|
||||
|
||||
public function maintenances($params = []){
|
||||
return $this->request( [
|
||||
"jsonrpc" => "2.0",
|
||||
"method" => "maintenance.get",
|
||||
"params" => $params,
|
||||
"id" => $this->id,
|
||||
"auth" => $this->token,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/*Helpers*/
|
||||
|
||||
private function request($body = []){
|
||||
if (empty($this->token)) {
|
||||
throw new Exception("you need to connect first", 1);
|
||||
}
|
||||
|
||||
$response = Http::withoutVerifying()->post($this->url . "/api_jsonrpc.php", $body);
|
||||
|
||||
if (!$response->successful()) {
|
||||
throw new Exception("Unable To Request", 1);
|
||||
}
|
||||
|
||||
$responseObject = $response->json();
|
||||
if (isset($responseObject['error'])) {
|
||||
throw new Exception($responseObject['error']['data'], $responseObject['error']['code']);
|
||||
}
|
||||
|
||||
$this->id++;
|
||||
return collect($responseObject["result"]);
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('maintenance_histories', function (Blueprint $table) {
|
||||
$table->string('hash');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
}
|
||||
};
|
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('hosts', function (Blueprint $table) {
|
||||
$table->string('display_name')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
}
|
||||
};
|
@ -3,9 +3,16 @@
|
||||
<div class="page-header">
|
||||
<h1>{{ __('boilerplate::hosts.title') }}</h1>
|
||||
|
||||
<button class="btn btn-primary" onclick="Livewire.dispatch('openModal', {livewireComponents: 'host.form', title: '{{ __('boilerplate::host.create') }}'})">
|
||||
<i class="me-2 fas fa-plus"></i><span>{{ __('boilerplate::ui.add') }}</span>
|
||||
</button>
|
||||
<div>
|
||||
<a class="btn btn-primary" href="{{ route('host.sync') }}">
|
||||
<i class="me-2 fas fa-sync-alt"></i><span>{{ __('boilerplate::ui.sync') }}</span>
|
||||
</a>
|
||||
|
||||
<button class="btn btn-primary"
|
||||
onclick="Livewire.dispatch('openModal', {livewireComponents: 'host.form', title: '{{ __('boilerplate::host.create') }}'})">
|
||||
<i class="me-2 fas fa-plus"></i><span>{{ __('boilerplate::ui.add') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@livewire('host.data-table', [], key('data-table'))
|
||||
|
@ -3,6 +3,9 @@
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::auth();
|
||||
Route::get('/', function () {
|
||||
return redirect()->route('login');
|
||||
});
|
||||
|
||||
Route::get('/maintenance/planned', [App\Http\Controllers\MaintenanceController::class, 'planned'])->name('maintenance.planned');
|
||||
Route::get('/maintenance/planned/{maintenance_history}', [App\Http\Controllers\MaintenanceController::class, 'plannedDetail'])->name('maintenance.planned.detail');
|
||||
@ -13,6 +16,9 @@
|
||||
|
||||
|
||||
Route::get('/host', [App\Http\Controllers\HostController::class, 'index'])->name('host');
|
||||
Route::get('/host/sync', [App\Http\Controllers\HostController::class, 'sync'])->name('host.sync');
|
||||
|
||||
|
||||
Route::get('/maintenance', [App\Http\Controllers\MaintenanceController::class, 'index'])->name('maintenance');
|
||||
Route::get('/tasks', [App\Http\Controllers\TaskController::class, 'index'])->name('tasks');
|
||||
|
||||
|
3
storage/app/.gitignore
vendored
3
storage/app/.gitignore
vendored
@ -1,3 +0,0 @@
|
||||
*
|
||||
!public/
|
||||
!.gitignore
|
2
storage/app/public/.gitignore
vendored
2
storage/app/public/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
*
|
||||
!.gitignore
|
BIN
storage/app/public/images/logo.png
Normal file
BIN
storage/app/public/images/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
Loading…
Reference in New Issue
Block a user