From ac7b4539ce2a9f79cbaddc7b9570c4208712d1ac Mon Sep 17 00:00:00 2001 From: Tony Murray Date: Thu, 18 Mar 2021 08:14:45 -0500 Subject: [PATCH] Fix Service Templates Dynamic (#12626) * Fix Service Templates Dynamic Remove dynamic groups type, it did not work. Rename and simplify field names. (fixing an issue with the builder where the rules field should be named rules) * update schema def * wrong method name in migration * fix rules builder * corerct call to apply * sqlite can't drop columns * correct column rename order on down. * fix sqlite again * fix whitespace --- .../Controllers/ServiceTemplateController.php | 60 +++----- app/Models/ServiceTemplate.php | 64 ++------ ..._230114_create_service_templates_table.php | 6 +- ...03_17_160729_service_templates_cleanup.php | 55 +++++++ misc/db_schema.yaml | 8 +- .../views/service-template/create.blade.php | 2 +- .../views/service-template/edit.blade.php | 4 +- .../views/service-template/form.blade.php | 143 ++++-------------- .../views/service-template/index.blade.php | 12 +- 9 files changed, 130 insertions(+), 224 deletions(-) create mode 100644 database/migrations/2021_03_17_160729_service_templates_cleanup.php diff --git a/app/Http/Controllers/ServiceTemplateController.php b/app/Http/Controllers/ServiceTemplateController.php index 6a0807074f..cf5da1cd63 100644 --- a/app/Http/Controllers/ServiceTemplateController.php +++ b/app/Http/Controllers/ServiceTemplateController.php @@ -69,11 +69,9 @@ class ServiceTemplateController extends Controller 'groups.*' => 'integer', 'devices' => 'array', 'devices.*' => 'integer', - 'type' => 'string', - 'dtype' => 'required|in:dynamic,static', - 'dgtype' => 'required|in:dynamic,static', - 'drules' => 'json|required_if:dtype,dynamic', - 'dgrules' => 'json|required_if:dgtype,dynamic', + 'check' => 'string', + 'type' => 'required|in:dynamic,static', + 'rules' => 'json|required_if:type,dynamic', 'param' => 'nullable|string', 'ip' => 'nullable|string', 'desc' => 'nullable|string', @@ -87,11 +85,9 @@ class ServiceTemplateController extends Controller $request->only( [ 'name', + 'check', 'type', - 'dtype', - 'dgtype', - 'drules', - 'dgrules', + 'rules', 'param', 'ip', 'desc', @@ -101,16 +97,14 @@ class ServiceTemplateController extends Controller ] ) ); - $template->drules = json_decode($request->drules); - $template->dgrules = json_decode($request->dgrules); + $template->rules = json_decode($request->rules); $template->save(); - if ($request->dtype == 'static') { + if ($request->type == 'static') { $template->devices()->sync($request->devices); } - if ($request->dgtype == 'static') { - $template->groups()->sync($request->groups); - } + + $template->groups()->sync($request->groups); Toastr::success(__('Service Template :name created', ['name' => $template->name])); return redirect()->route('services.templates.index'); @@ -165,15 +159,13 @@ class ServiceTemplateController extends Controller } ), ], - 'dtype' => 'required|in:dynamic,static', - 'drules' => 'json|required_if:dtype,dynamic', + 'type' => 'required|in:dynamic,static', + 'rules' => 'json|required_if:type,dynamic', 'devices' => 'array', 'devices.*' => 'integer', - 'dgtype' => 'required|in:dynamic,static', - 'dgrules' => 'json|required_if:dgtype,dynamic', 'groups' => 'array', 'groups.*' => 'integer', - 'type' => 'string', + 'check' => 'string', 'param' => 'nullable|string', 'ip' => 'nullable|string', 'desc' => 'nullable|string', @@ -187,11 +179,9 @@ class ServiceTemplateController extends Controller $request->only( [ 'name', + 'check', 'type', - 'dtype', - 'dgtype', - 'drules', - 'dgrules', + 'rules', 'param', 'ip', 'desc', @@ -203,27 +193,22 @@ class ServiceTemplateController extends Controller ); $devices_updated = false; - if ($template->dtype == 'static') { + if ($template->type == 'static') { // sync device_ids from input $updated = $template->devices()->sync($request->get('devices', [])); // check for attached/detached/updated $devices_updated = array_sum(array_map(function ($device_ids) { return count($device_ids); }, $updated)) > 0; - } else { - $template->drules = json_decode($request->drules); - } - - $device_groups_updated = false; - if ($template->dgtype == 'static') { + } elseif ($template->type == 'dynamic') { + $template->rules = json_decode($request->rules); + } elseif ($template->type == 'groups') { // sync device_group_ids from input $updated = $template->groups()->sync($request->get('groups', [])); // check for attached/detached/updated $device_groups_updated = array_sum(array_map(function ($device_group_ids) { return count($device_group_ids); }, $updated)) > 0; - } else { - $template->dgrules = json_decode($request->dgrules); } if ($template->isDirty() || $devices_updated || $device_groups_updated) { @@ -237,8 +222,7 @@ class ServiceTemplateController extends Controller } } catch (\Illuminate\Database\QueryException $e) { return redirect()->back()->withInput()->withErrors([ - 'drules' => __('Rules resulted in invalid query: ') . $e->getMessage(), - 'dgrules' => __('Rules resulted in invalid query: ') . $e->getMessage(), + 'rules' => __('Rules resulted in invalid query: ') . $e->getMessage(), ]); } } else { @@ -264,7 +248,7 @@ class ServiceTemplateController extends Controller ], [ 'service_name' => $template->name, - 'service_type' => $template->type, + 'service_type' => $template->check, 'service_template_id' => $template->id, 'service_param' => $template->param, 'service_ip' => $template->ip, @@ -295,7 +279,7 @@ class ServiceTemplateController extends Controller ], [ 'service_name' => $template->name, - 'service_type' => $template->type, + 'service_type' => $template->check, 'service_template_id' => $template->id, 'service_param' => $template->param, 'service_ip' => $template->ip, @@ -318,7 +302,7 @@ class ServiceTemplateController extends Controller public function applyAll() { foreach (ServiceTemplate::all() as $template) { - ServiceTemplateController::apply($template); + $this->apply($template); } $msg = __('All Service Templates have been applied'); diff --git a/app/Models/ServiceTemplate.php b/app/Models/ServiceTemplate.php index ea0e9f75e4..f22cd085d3 100644 --- a/app/Models/ServiceTemplate.php +++ b/app/Models/ServiceTemplate.php @@ -36,11 +36,9 @@ class ServiceTemplate extends BaseModel protected $fillable = [ 'id', 'ip', + 'check', 'type', - 'dtype', - 'dgtype', - 'drules', - 'dgrules', + 'rules', 'desc', 'param', 'ignore', @@ -58,8 +56,7 @@ class ServiceTemplate extends BaseModel protected $casts = [ 'ignore' => 'integer', 'disabled' => 'integer', - 'drules' => 'array', - 'dgrules' => 'array', + 'rules' => 'array', ]; public static function boot() @@ -72,21 +69,15 @@ class ServiceTemplate extends BaseModel }); static::saving(function (ServiceTemplate $template) { - if ($template->dtype == 'dynamic' and $template->isDirty('drules')) { - $template->drules = $template->getDeviceParser()->generateJoins()->toArray(); - } - if ($template->dgtype == 'dynamic' and $template->isDirty('dgrules')) { - $template->dgrules = $template->getDeviceGroupParser()->generateJoins()->toArray(); + if ($template->type == 'dynamic' and $template->isDirty('rules')) { + $template->rules = $template->getDeviceParser()->generateJoins()->toArray(); } }); static::saved(function (ServiceTemplate $template) { - if ($template->dtype == 'dynamic' and $template->isDirty('drules')) { + if ($template->type == 'dynamic' and $template->isDirty('rules')) { $template->updateDevices(); } - if ($template->dgtype == 'dynamic' and $template->isDirty('dgrules')) { - $template->updateGroups(); - } }); } @@ -97,23 +88,12 @@ class ServiceTemplate extends BaseModel */ public function updateDevices() { - if ($this->dtype == 'dynamic') { - $this->devices()->sync(QueryBuilderFluentParser::fromJSON($this->drules)->toQuery() + if ($this->type == 'dynamic') { + $this->devices()->sync(QueryBuilderFluentParser::fromJSON($this->rules)->toQuery() ->distinct()->pluck('devices.device_id')); } } - /** - * Update device groups included in this template (dynamic only) - */ - public function updateGroups() - { - if ($this->dgtype == 'dynamic') { - $this->groups()->sync(QueryBuilderFluentParser::fromJSON($this->dgrules)->toQuery() - ->distinct()->pluck('device_groups.id')); - } - } - /** * Update the device template groups for the given device or device_id * @@ -139,7 +119,7 @@ class ServiceTemplate extends BaseModel ->get() ->filter(function ($template) use ($device) { /** @var ServiceTemplate $template */ - if ($template->dtype == 'dynamic') { + if ($template->type == 'dynamic') { try { return $template->getDeviceParser() ->toQuery() @@ -185,20 +165,6 @@ class ServiceTemplate extends BaseModel }]) ->get() ->filter(function ($template) use ($deviceGroup) { - /** @var ServiceTemplate $template */ - if ($template->dgtype == 'dynamic') { - try { - return $template->getDeviceGroupParser() - ->toQuery() - ->where('device_groups.id', $deviceGroup->id) - ->exists(); - } catch (\Illuminate\Database\QueryException $e) { - Log::error("Service Template '$template->name' generates invalid query: " . $e->getMessage()); - - return false; - } - } - // for static, if this device group is include, keep it. return $template->groups ->where('device_group_id', $deviceGroup->id) @@ -215,17 +181,7 @@ class ServiceTemplate extends BaseModel */ public function getDeviceParser() { - return QueryBuilderFluentParser::fromJson($this->drules); - } - - /** - * Get a query builder parser instance from this Service Template device group rule - * - * @return QueryBuilderFluentParser - */ - public function getDeviceGroupParser() - { - return QueryBuilderFluentParser::fromJson($this->dgrules); + return QueryBuilderFluentParser::fromJson($this->rules); } // ---- Query Scopes ---- diff --git a/database/migrations/2020_09_18_230114_create_service_templates_table.php b/database/migrations/2020_09_18_230114_create_service_templates_table.php index b58f6ee417..95a81b3140 100644 --- a/database/migrations/2020_09_18_230114_create_service_templates_table.php +++ b/database/migrations/2020_09_18_230114_create_service_templates_table.php @@ -17,9 +17,11 @@ class CreateServiceTemplatesTable extends Migration $table->text('ip')->nullable()->default(null); $table->string('type'); $table->string('dtype', 16)->default('static'); - $table->string('dgtype', 16)->default('static'); $table->text('drules')->nullable(); - $table->text('dgrules')->nullable(); + if (\LibreNMS\DB\Eloquent::getDriver() !== 'sqlite') { + $table->string('dgtype', 16)->default('static'); + $table->text('dgrules')->nullable(); + } $table->text('desc')->nullable()->default(null); $table->text('param')->nullable()->default(null); $table->boolean('ignore')->default(0); diff --git a/database/migrations/2021_03_17_160729_service_templates_cleanup.php b/database/migrations/2021_03_17_160729_service_templates_cleanup.php new file mode 100644 index 0000000000..bf7abb1ff8 --- /dev/null +++ b/database/migrations/2021_03_17_160729_service_templates_cleanup.php @@ -0,0 +1,55 @@ +renameColumn('type', 'check'); + }); + Schema::table('service_templates', function (Blueprint $table) { + $table->renameColumn('dtype', 'type'); + }); + Schema::table('service_templates', function (Blueprint $table) { + $table->renameColumn('drules', 'rules'); + }); + if (\LibreNMS\DB\Eloquent::getDriver() !== 'sqlite') { + Schema::table('service_templates', function (Blueprint $table) { + $table->dropColumn(['dgtype', 'dgrules']); + }); + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('service_templates', function (Blueprint $table) { + $table->renameColumn('type', 'dtype'); + }); + Schema::table('service_templates', function (Blueprint $table) { + $table->renameColumn('check', 'type'); + }); + Schema::table('service_templates', function (Blueprint $table) { + $table->renameColumn('rules', 'drules'); + }); + if (\LibreNMS\DB\Eloquent::getDriver() !== 'sqlite') { + Schema::table('service_templates', function (Blueprint $table) { + $table->string('dgtype', 16)->default('static'); + $table->text('dgrules')->nullable(); + }); + } + } +} diff --git a/misc/db_schema.yaml b/misc/db_schema.yaml index e7ee669e94..0e24d9157a 100644 --- a/misc/db_schema.yaml +++ b/misc/db_schema.yaml @@ -1763,11 +1763,9 @@ service_templates: Columns: - { Field: id, Type: 'int unsigned', 'Null': false, Extra: auto_increment } - { Field: ip, Type: text, 'Null': true, Extra: '' } - - { Field: type, Type: varchar(255), 'Null': false, Extra: '' } - - { Field: dtype, Type: varchar(16), 'Null': false, Extra: '', Default: static } - - { Field: dgtype, Type: varchar(16), 'Null': false, Extra: '', Default: static } - - { Field: drules, Type: text, 'Null': true, Extra: '' } - - { Field: dgrules, Type: text, 'Null': true, Extra: '' } + - { Field: check, Type: varchar(255), 'Null': false, Extra: '' } + - { Field: type, Type: varchar(16), 'Null': false, Extra: '', Default: static } + - { Field: rules, Type: text, 'Null': true, Extra: '' } - { Field: desc, Type: text, 'Null': true, Extra: '' } - { Field: param, Type: text, 'Null': true, Extra: '' } - { Field: ignore, Type: tinyint, 'Null': false, Extra: '', Default: '0' } diff --git a/resources/views/service-template/create.blade.php b/resources/views/service-template/create.blade.php index afc883d3f2..54673a1d53 100644 --- a/resources/views/service-template/create.blade.php +++ b/resources/views/service-template/create.blade.php @@ -6,7 +6,7 @@
+ class="form-horizontal service-template-form col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2 col-sm-12">

@lang('Create Service Template')

Service Template will created for the specified Device Group.
@csrf diff --git a/resources/views/service-template/edit.blade.php b/resources/views/service-template/edit.blade.php index 7af99d7d7d..0a906ac99e 100644 --- a/resources/views/service-template/edit.blade.php +++ b/resources/views/service-template/edit.blade.php @@ -6,9 +6,9 @@
+ class="form-horizontal service-template-form col-md-10 col-md-offset-1 col-sm-12">

@lang('Edit Service Template'): {{ $template->name }}

-
Service Template will edited for the specified Device Group.
+
Service Template will be edited for the specified Device Group.
{{ method_field('PUT') }} @csrf
diff --git a/resources/views/service-template/form.blade.php b/resources/views/service-template/form.blade.php index 2297cdbf19..6f1a548749 100644 --- a/resources/views/service-template/form.blade.php +++ b/resources/views/service-template/form.blade.php @@ -6,28 +6,28 @@
-
- +
+
- + @if(old('type', $template->type) == 'static') selected @endif>@lang('Static') + @if(old('type', $template->type) == 'dynamic') selected @endif>@lang('Dynamic') - {{ $errors->first('dtype') }} + {{ $errors->first('type') }}
-
- + -