From ccbe6cfd2bd07bbe41dc221e81247ef316903c89 Mon Sep 17 00:00:00 2001
From: Alexander Olofsson <alexander.olofsson@liu.se>
Date: Mon, 18 Sep 2023 10:32:52 +0200
Subject: [PATCH] Splitting out generic model components

---
 lib/liudesk_cmdb/models/generic.rb            |  2 +
 lib/liudesk_cmdb/models/generic/client.rb     | 25 ++-----------
 .../models/generic/computerlab.rb             | 24 ++++++++++++
 .../models/generic/with_hardware.rb           | 37 +++++++++++++++++++
 lib/liudesk_cmdb/models/linux_computerlab.rb  |  2 +-
 lib/liudesk_cmdb/models/server.rb             | 16 ++------
 .../models/windows_computerlab.rb             |  2 +-
 7 files changed, 72 insertions(+), 36 deletions(-)
 create mode 100644 lib/liudesk_cmdb/models/generic/computerlab.rb
 create mode 100644 lib/liudesk_cmdb/models/generic/with_hardware.rb

diff --git a/lib/liudesk_cmdb/models/generic.rb b/lib/liudesk_cmdb/models/generic.rb
index 90ce93e..60344d9 100644
--- a/lib/liudesk_cmdb/models/generic.rb
+++ b/lib/liudesk_cmdb/models/generic.rb
@@ -3,4 +3,6 @@
 # Storage for generic model components
 module LiudeskCMDB::Models::Generic
   autoload :Client, "liudesk_cmdb/models/generic/client"
+  autoload :Computerlab, "liudesk_cmdb/models/generic/computerlab"
+  autoload :WithHardware, "liudesk_cmdb/models/generic/with_hardware"
 end
diff --git a/lib/liudesk_cmdb/models/generic/client.rb b/lib/liudesk_cmdb/models/generic/client.rb
index 38ab387..d4ad152 100644
--- a/lib/liudesk_cmdb/models/generic/client.rb
+++ b/lib/liudesk_cmdb/models/generic/client.rb
@@ -16,18 +16,18 @@ module LiudeskCMDB::Models::Generic
   module Client
     def self.included(base)
       base.class_eval do
+        base.include WithHardware
+
         identifier :hostname
 
         access_fields \
           :hostname, :division, :asset_owner, :certificate_information,
-          :network_access_role, :hardware_id,
+          :network_access_role,
           :operating_system_type, :operating_system, :operating_system_install_date,
           :ad_creation_date, :active_directory_ou, :client_classification,
-          :management_system, :management_system_id, :network_certificate_ca,
-          :misc_information
+          :management_system, :management_system_id, :network_certificate_ca
 
         field_attributes :hostname, name: "hostName"
-        field_attributes :hardware_id, name: "hardwareID"
         field_attributes :active_directory_ou, name: "activeDirectoryOU"
         field_attributes :operating_system_install_date, convert: Time
         field_attributes :ad_creation_date, convert: Time
@@ -37,22 +37,5 @@ module LiudeskCMDB::Models::Generic
     def to_s
       hostname
     end
-
-    # Get an instance of the underlying hardware object
-    #
-    # @return [HardwareV1] the hardware underlying this client
-    def hardware
-      @hardware ||= LiudeskCMDB::Models::HardwareV1.get(client, hardware_id)
-    end
-
-    # Change the underlying hardware object
-    #
-    # @param hardware [HardwareV1] the new hardware object to assign
-    def hardware=(hardware)
-      raise ArgumentError, "Must be a HardwareV1" unless hardware.is_a? LinudeskCMDB::Models::HardwareV1
-
-      self.hardware_id = hardware.guid if hardware
-      @hardware = hardware
-    end
   end
 end
diff --git a/lib/liudesk_cmdb/models/generic/computerlab.rb b/lib/liudesk_cmdb/models/generic/computerlab.rb
new file mode 100644
index 0000000..fef1e05
--- /dev/null
+++ b/lib/liudesk_cmdb/models/generic/computerlab.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module LiudeskCMDB::Models::Generic
+  # Generic client model, for Linux/Windows/Mac ComputerLab assets
+  #
+  # @!attribute [r] created_date
+  #   @return [Time] the date of creation
+  # @!attribute [r] updated_date
+  #   @return [Time] the date of change
+  # @!attribute hardware_id
+  #   @return [String] the ID for the underlying HardwareV1 object
+  # @!attribute hostname
+  #   @return [String] the hostname of the client
+  # @!attribute division
+  #   @return [String?] the division the client belongs to
+  module Computerlab
+    def self.included(base)
+      base.include Client
+      base.class_eval do
+        access_fields :misc_information
+      end
+    end
+  end
+end
diff --git a/lib/liudesk_cmdb/models/generic/with_hardware.rb b/lib/liudesk_cmdb/models/generic/with_hardware.rb
new file mode 100644
index 0000000..a094d18
--- /dev/null
+++ b/lib/liudesk_cmdb/models/generic/with_hardware.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+module LiudeskCMDB::Models::Generic
+  # Handles retrieving and changing attached hardware on a model
+  module WithHardware
+    def self.included(base)
+      base.class_eval do
+        access_fields :hardware_id
+
+        field_attributes :hardware_id, name: "hardwareID"
+      end
+    end
+
+    # Get an instance of the underlying hardware object
+    #
+    # @return [HardwareV1] the hardware underlying this client
+    def hardware
+      if hardware_id == "Disabled for listing due to performance issue"
+        self.hardware_id = self.class.get(@client, identifier).hardware_id
+      end
+
+      return unless hardware_id
+
+      @hardware ||= LiudeskCMDB::Models::HardwareV1.get(client, hardware_id)
+    end
+
+    # Change the underlying hardware object
+    #
+    # @param hardware [HardwareV1] the new hardware object to assign
+    def hardware=(hardware)
+      raise ArgumentError, "Must be a HardwareV1" if hardware && !hardware.is_a?(LinudeskCMDB::Models::HardwareV1)
+
+      self.hardware_id = hardware.guid if hardware
+      @hardware = hardware
+    end
+  end
+end
diff --git a/lib/liudesk_cmdb/models/linux_computerlab.rb b/lib/liudesk_cmdb/models/linux_computerlab.rb
index 3c57c18..a3d98c1 100644
--- a/lib/liudesk_cmdb/models/linux_computerlab.rb
+++ b/lib/liudesk_cmdb/models/linux_computerlab.rb
@@ -3,7 +3,7 @@
 module LiudeskCMDB::Models
   # Linux Client v1
   class LinuxComputerlabV1 < LiudeskCMDB::Model
-    include LiudeskCMDB::Models::Generic::Client
+    include LiudeskCMDB::Models::Generic::Computerlab
 
     api_name "ComputerLabs"
     model_name "linux"
diff --git a/lib/liudesk_cmdb/models/server.rb b/lib/liudesk_cmdb/models/server.rb
index 78f21ea..f67b74c 100644
--- a/lib/liudesk_cmdb/models/server.rb
+++ b/lib/liudesk_cmdb/models/server.rb
@@ -3,6 +3,8 @@
 module LiudeskCMDB::Models
   # Server OS v1
   class ServerV1 < LiudeskCMDB::Model
+    include LiudeskCMDB::Models::Generic::WithHardware
+
     model_name "Server"
     model_version :v1
 
@@ -10,13 +12,12 @@ module LiudeskCMDB::Models
 
     access_fields \
       :hostname, :division, :asset_owner, :certificate_information,
-      :network_access_role, :hardware_id,
+      :network_access_role,
       :operating_system_type, :operating_system, :operating_system_install_date,
       :ad_creation_date, :active_directory_ou, :group_or_lab,
       :contact_information, :misc_information, :management_system, :management_system_id, :icinga_link, :foreman_link
 
     field_attributes :hostname, name: "hostName"
-    field_attributes :hardware_id, name: "hardwareID"
     field_attributes :active_directory_ou, name: "activeDirectoryOU"
     field_attributes :operating_system_install_date, convert: Time
     field_attributes :ad_creation_date, convert: Time
@@ -24,16 +25,5 @@ module LiudeskCMDB::Models
     def to_s
       hostname
     end
-
-    def hardware
-      @hardware ||= LiudeskCMDB::Models::HardwareV1.get(client, hardware_id)
-    end
-
-    def hardware=(hardware)
-      raise ArgumentError, "Must be a HardwareV1" unless hardware.is_a? LinudeskCMDB::Models::HardwareV1
-
-      @hardware = hardware
-      self.hardware_id = hardware.guid if hardware
-    end
   end
 end
diff --git a/lib/liudesk_cmdb/models/windows_computerlab.rb b/lib/liudesk_cmdb/models/windows_computerlab.rb
index 6d5829a..1ef09b0 100644
--- a/lib/liudesk_cmdb/models/windows_computerlab.rb
+++ b/lib/liudesk_cmdb/models/windows_computerlab.rb
@@ -3,7 +3,7 @@
 module LiudeskCMDB::Models
   # Windows ComputerLab v1
   class WindowsComputerlabV1 < LiudeskCMDB::Model
-    include LiudeskCMDB::Models::Generic::Client
+    include LiudeskCMDB::Models::Generic::Computerlab
 
     api_name "ComputerLabs"
     model_name "windows"
-- 
GitLab