diff --git a/README.md b/README.md index a421608..f2a5ae0 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,8 @@ Netbox object set to be imported _Import types `Devices` and `Virtual Machines` also import linked Services, linked Contacts, linked interfaces and IP Ranges from Netbox_ _Import type `FHRP Groups Split (on IP)` also import linked IP Ranges from Netbox_ +_Import type `Virtual Chassis` imports `Devices` using the netbox filter `?virtual_chassis_member=True&vc_position=1` and combines the interfaces of all members. So all the informations like primary_ip etc. are coming from the member on position 1 within the chassis._ + #### Flatten seperator This will take nested data (`{ "foo": { "bar": "123 }, "bar": "321" }`) and use the seperator specified to flatten it (`{ foo__bar: 123, "bar": 321" }`) diff --git a/library/Netbox/Netbox.php b/library/Netbox/Netbox.php index 40b3e3c..da8f899 100644 --- a/library/Netbox/Netbox.php +++ b/library/Netbox/Netbox.php @@ -632,6 +632,29 @@ public function deviceInterfaces($filter, int $limit = 0) return $this->get_netbox("/dcim/interfaces/?" . $this->default_filter($filter, ""), $limit); } + public function virtualChassisMaster($filter, int $limit = 0) + { + $this->object_type = 'virtual_chassis'; + $this->type_map = array( + "role" => "device_role", + "platform" => "platform", + "location" => "location", + "rack" => "rack", + "cluster" => "cluster", + "site" => "site", + "tenant" => "tenant", + "members" => "members" + ); + return $this->get_netbox("/dcim/devices/?virtual_chassis_member=True&vc_position=1&" . $this->default_filter($filter, "status=active"), $limit); + } + + public function virtualChassis($filter, int $limit = 0) + { + $this->object_type = 'virtual_chassis'; + $this->type_map = array(); + return $this->get_netbox("/dcim/virtual-chassis/?" . $this->default_filter($filter, "status=active"), $limit); + } + // IPAM public function ipAddresses($filter, int $limit = 0) { diff --git a/library/Netbox/NetboxMerge.php b/library/Netbox/NetboxMerge.php index a616ba0..e4bce18 100644 --- a/library/Netbox/NetboxMerge.php +++ b/library/Netbox/NetboxMerge.php @@ -40,6 +40,21 @@ public static function getLinkedObjects($netboxLinked, $linkservices, $linkconta } $interfaces = array_merge($interfaces, $netboxLinked->deviceInterfaces($device_filter, 0)); } + if ($content_type == "dcim.virtual_chassis"){ + $virtual_chassis_filter = ""; + foreach ($things as $virtual_chassis_master) { + $virtual_chassis_filter .= "&virtual_chassis_id=" . $virtual_chassis_master->virtual_chassis->id; + if (strlen($virtual_chassis_filter) > 1500) { + $interfaces = array_merge($interfaces, $netboxLinked->deviceInterfaces($virtual_chassis_filter, 0)); + $virtual_chassis_filter = ""; + } + $virtual_chassis = $netboxLinked->virtualChassis("id=" . $virtual_chassis_master->virtual_chassis->id); + if (count($virtual_chassis) === 1) { + $virtual_chassis_master->members = reset($virtual_chassis)->members; + } + } + $interfaces = array_merge($interfaces, $netboxLinked->deviceInterfaces($virtual_chassis_filter, 0)); + } } $module_bays = array(); $modules = array(); @@ -71,12 +86,18 @@ public static function get_interfaces($interfaces, $things, $content_type) $output = array(); $content_name = (strpos($content_type, 'virtualmachine') !== false) ? 'virtual_machine' : 'device'; foreach ($things as $thing) { + if ($content_type == "dcim.virtual_chassis"){ + $member_ids = array(); + foreach ($thing->members as $member) { + array_push($member_ids,$member->id); + } + } $thing->interfaces_down = array(); $thing->interfaces_up = array(); $thing->interfaces_down_dict = (object)[]; $thing->interfaces_up_dict = (object)[]; foreach ($interfaces as $interface) { - if ((isset($interface->{$content_name}->id) && $interface->{$content_name}->id == $thing->id) && (!isset($interface->custom_fields->icinga_monitored) || $interface->custom_fields->icinga_monitored === true)) { + if ((isset($interface->{$content_name}->id) && ($interface->{$content_name}->id == $thing->id || (isset($member_ids) && in_array($interface->{$content_name}->id,$member_ids)))) && (!isset($interface->custom_fields->icinga_monitored) || $interface->custom_fields->icinga_monitored === true)) { $icinga_dict = isset($interface->custom_fields->icinga_dict) ? $interface->custom_fields->icinga_dict : (object)[]; // {netbox_fields: {index_key:label, example_key:custom_fields.example}} if (isset($icinga_dict->netbox_fields)){ diff --git a/library/Netbox/ProvidedHook/Director/ImportSource.php b/library/Netbox/ProvidedHook/Director/ImportSource.php index 4647986..9c0c825 100644 --- a/library/Netbox/ProvidedHook/Director/ImportSource.php +++ b/library/Netbox/ProvidedHook/Director/ImportSource.php @@ -28,6 +28,9 @@ class ImportSource extends ImportSourceHook const ManufacturerMode = 25; const DeviceInterfaceMode = 26; +// Virtual Chassis + const VirtualChassisMode = 28; + // IPAM const IPAddressMode = 30; const IPRangeMode = 32; @@ -119,6 +122,9 @@ public static function addSettingsFormFields(QuickForm $form) self::DeviceTypeMode => $form->translate('Device Types'), self::ManufacturerMode => $form->translate('Manufacturers'), self::DeviceInterfaceMode => $form->translate('Device Interfaces'), + + // Virtual Chassis + self::VirtualChassisMode => $form->translate('Virtual Chassis'), // IPAM self::IPAddressMode => $form->translate('IP Addresses'), @@ -282,6 +288,9 @@ public function fetchData(int $limit = 0) return $netbox->manufacturers($filter, $limit); case self::DeviceInterfaceMode: return $netbox->deviceInterfaces($filter, $limit); + case self::VirtualChassisMode: + $netboxLinked = Netbox::fromConfig($baseurl, $apitoken, $proxy, $sslenable); + return NetboxMerge::getLinkedObjects($netboxLinked, $linkservices, $linkcontacts, $linkinterfaces, $linkmodulebays, "dcim.virtual_chassis", $netbox->virtualChassisMaster($filter, $limit)); // IPAM case self::IPAddressMode: