From 4ba7633afca007ba5b556ce46d8a7136dd2ad20b Mon Sep 17 00:00:00 2001 From: Dmitry Volodin Date: Thu, 24 Sep 2020 11:33:09 +0300 Subject: [PATCH] #1363 ifdesc: Interface autocreation --- ...ctprofile_enable_interface_autocreation.py | 19 ++++++++++++ sa/models/managedobjectprofile.py | 2 ++ services/discovery/jobs/box/ifdesc.py | 29 +++++++++++++++++++ ui/web/sa/managedobjectprofile/Application.js | 11 +++++-- ui/web/sa/managedobjectprofile/Model.js | 4 +++ 5 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 sa/migrations/0210_managedobjectprofile_enable_interface_autocreation.py diff --git a/sa/migrations/0210_managedobjectprofile_enable_interface_autocreation.py b/sa/migrations/0210_managedobjectprofile_enable_interface_autocreation.py new file mode 100644 index 0000000000..b50ae38714 --- /dev/null +++ b/sa/migrations/0210_managedobjectprofile_enable_interface_autocreation.py @@ -0,0 +1,19 @@ +# ---------------------------------------------------------------------- +# ManagedObjectProfile.enable_interface_autocreation +# ---------------------------------------------------------------------- +# Copyright (C) 2007-2020 The NOC Project +# See LICENSE for details +# ---------------------------------------------------------------------- + +# NOC modules +from noc.core.migration.base import BaseMigration +from django.db import models + + +class Migration(BaseMigration): + def migrate(self): + self.db.add_column( + "sa_managedobjectprofile", + "enable_interface_autocreation", + models.BooleanField(default=False), + ) diff --git a/sa/models/managedobjectprofile.py b/sa/models/managedobjectprofile.py index a9671a74bf..65b5a0f166 100644 --- a/sa/models/managedobjectprofile.py +++ b/sa/models/managedobjectprofile.py @@ -359,6 +359,8 @@ class ManagedObjectProfile(NOCModel): # Jinja2 tempplate for segment name # object and interface context variables are exist autosegmentation_segment_name = models.CharField(max_length=255, default="{{object.name}}") + # Auto-create interface to link + enable_interface_autocreation = models.BooleanField(default=False) # Integration with external NRI and TT systems # Reference to remote system object has been imported from remote_system = DocumentReferenceField(RemoteSystem, null=True, blank=True) diff --git a/services/discovery/jobs/box/ifdesc.py b/services/discovery/jobs/box/ifdesc.py index fcefffd6e9..b96f7010af 100644 --- a/services/discovery/jobs/box/ifdesc.py +++ b/services/discovery/jobs/box/ifdesc.py @@ -206,6 +206,9 @@ class IfDescCheck(TopologyDiscoveryCheck): ) -> Optional[Interface]: ifaces = self.get_object_interfaces(mo) if not ifaces: + if interface: + # Object has no interfaces but may allow to auto-create one + return self.maybe_create_interface(mo, interface) return None if interface: interface = self.get_remote_interface(mo, interface) @@ -213,6 +216,8 @@ class IfDescCheck(TopologyDiscoveryCheck): iface = ifaces.get(interface) if iface: return iface + # Target interface is not found, but object may allow to auto-create one + return self.maybe_create_interface(mo, interface) if ifindex: ifi = int(ifindex) matched = [x for x in ifaces.values() if x.ifindex == ifi] @@ -229,3 +234,27 @@ class IfDescCheck(TopologyDiscoveryCheck): } self.if_cache[mo.id] = ifaces return ifaces + + def maybe_create_interface(self, mo: ManagedObject, name: str) -> Optional[Interface]: + """ + Auto-create remote interface, if possible + + :param mo: + :param name: + :return: + """ + if self.object.object_profile.ifdesc_symmetric: + return None # Meaningless for symmetric ifdesc + if ( + self.object.object_profile.enable_box_discovery_interface + or not mo.object_profile.enable_interface_autocreation + ): + return None # Auto-creation is disabled + # Create interface + self.logger.info("Auto-creating interface %s:%s", mo.name, name) + iface = Interface(managed_object=mo, type="physical", name=name) + iface.save() + # Adjust cache + if mo.id in self.if_cache: + self.if_cache[mo.id][iface.name] = iface + return iface diff --git a/ui/web/sa/managedobjectprofile/Application.js b/ui/web/sa/managedobjectprofile/Application.js index 904ca025e2..6549c367ea 100644 --- a/ui/web/sa/managedobjectprofile/Application.js +++ b/ui/web/sa/managedobjectprofile/Application.js @@ -836,8 +836,15 @@ Ext.define("NOC.sa.managedobjectprofile.Application", { bind: { disabled: "{!enableBoxDiscoveryInterface.checked}" }, - uiStyle: "medium", - colspan: 2 + uiStyle: "medium" + }, + { + name: "enable_interface_autocreation", + xtype: "checkbox", + boxLabel: __("Enable Autocreation"), + bind: { + disabled: "{enableBoxDiscoveryInterface.checked}" + } }, { name: "enable_box_discovery_id", diff --git a/ui/web/sa/managedobjectprofile/Model.js b/ui/web/sa/managedobjectprofile/Model.js index fe28103e24..87c14efeab 100644 --- a/ui/web/sa/managedobjectprofile/Model.js +++ b/ui/web/sa/managedobjectprofile/Model.js @@ -875,6 +875,10 @@ Ext.define("NOC.sa.managedobjectprofile.Model", { name: "rca_downlink_merge_window", type: "integer", defaultValue: 120 + }, + { + name: "enable_interface_autocreation", + type: "boolean" } ] }); -- GitLab