diff --git a/Gemfile b/Gemfile index 45e3cc721b3345ad5df53b38a8ee5b47220cdb68..4be409b50b8c8530a9373f6ec372e00a589287c8 100644 --- a/Gemfile +++ b/Gemfile @@ -8,3 +8,4 @@ gemspec gem "minitest", "~> 5.0" gem "rake", "~> 13.0" gem "rubocop", "~> 1.21" +gem "webmock" diff --git a/lib/liudesk_cmdb/models/generic.rb b/lib/liudesk_cmdb/models/generic.rb new file mode 100644 index 0000000000000000000000000000000000000000..90ce93e4b3e9b933613d1150c4f12a014f16d353 --- /dev/null +++ b/lib/liudesk_cmdb/models/generic.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +# Storage for generic model components +module LiudeskCMDB::Models::Generic + autoload :Client, "liudesk_cmdb/models/generic/client" +end diff --git a/lib/liudesk_cmdb/models/generic/client.rb b/lib/liudesk_cmdb/models/generic/client.rb new file mode 100644 index 0000000000000000000000000000000000000000..38ab3871822b31cecdd81bc297cd3743b8605ec8 --- /dev/null +++ b/lib/liudesk_cmdb/models/generic/client.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +module LiudeskCMDB::Models::Generic + # Generic client model, for Linux/Windows/Mac Client/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 Client + def self.included(base) + base.class_eval do + identifier :hostname + + access_fields \ + :hostname, :division, :asset_owner, :certificate_information, + :network_access_role, :hardware_id, + :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 + + 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 + end + end + + 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/linux_client.rb b/lib/liudesk_cmdb/models/linux_client.rb index 8ced5f52625cc47365c21882e0170844072aa757..de6aef4919d6b8c2da06c191f45263dd15036f14 100644 --- a/lib/liudesk_cmdb/models/linux_client.rb +++ b/lib/liudesk_cmdb/models/linux_client.rb @@ -2,56 +2,11 @@ module LiudeskCMDB::Models # Linux Client v1 - # - # @!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 class LinuxClientV1 < LiudeskCMDB::Model + include LiudeskCMDB::Models::Generic::Client + api_name "Clients" model_name "linux" model_version :v1 - - identifier :hostname - - access_fields \ - :hostname, :division, :asset_owner, :certificate_information, - :network_access_role, :hardware_id, - :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 - - 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 - - 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/linux_computerlab.rb b/lib/liudesk_cmdb/models/linux_computerlab.rb new file mode 100644 index 0000000000000000000000000000000000000000..3c57c18f3f9061ba1d5fb5f04ba8682560f5270c --- /dev/null +++ b/lib/liudesk_cmdb/models/linux_computerlab.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module LiudeskCMDB::Models + # Linux Client v1 + class LinuxComputerlabV1 < LiudeskCMDB::Model + include LiudeskCMDB::Models::Generic::Client + + api_name "ComputerLabs" + model_name "linux" + model_version :v1 + end +end diff --git a/lib/liudesk_cmdb/models/mac_client.rb b/lib/liudesk_cmdb/models/mac_client.rb new file mode 100644 index 0000000000000000000000000000000000000000..ae474cf3e6ba0454cc9143e88cf27dfa78bc29f3 --- /dev/null +++ b/lib/liudesk_cmdb/models/mac_client.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module LiudeskCMDB::Models + # Mac Client v1 + class MacClientV1 < LiudeskCMDB::Model + include LiudeskCMDB::Models::Generic::Client + + api_name "Clients" + model_name "mac" + model_version :v1 + end +end diff --git a/lib/liudesk_cmdb/models/windows_client.rb b/lib/liudesk_cmdb/models/windows_client.rb new file mode 100644 index 0000000000000000000000000000000000000000..3a8735e87cc1448dcebe1c900830df93879110cd --- /dev/null +++ b/lib/liudesk_cmdb/models/windows_client.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module LiudeskCMDB::Models + # Windows Client v1 + class WindowsClientV1 < LiudeskCMDB::Model + include LiudeskCMDB::Models::Generic::Client + + api_name "Clients" + model_name "windows" + model_version :v1 + end +end diff --git a/lib/liudesk_cmdb/models/windows_computerlab.rb b/lib/liudesk_cmdb/models/windows_computerlab.rb new file mode 100644 index 0000000000000000000000000000000000000000..6d5829a51a0c63182218b43887cc3feb00cd35e7 --- /dev/null +++ b/lib/liudesk_cmdb/models/windows_computerlab.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module LiudeskCMDB::Models + # Windows ComputerLab v1 + class WindowsComputerlabV1 < LiudeskCMDB::Model + include LiudeskCMDB::Models::Generic::Client + + api_name "ComputerLabs" + model_name "windows" + model_version :v1 + end +end diff --git a/test/fixtures/get_linuxclient.json b/test/fixtures/get_linuxclient.json new file mode 100644 index 0000000000000000000000000000000000000000..de456f7e687aba3f78d15e2e83b34e6c1e225c5c --- /dev/null +++ b/test/fixtures/get_linuxclient.json @@ -0,0 +1,20 @@ +{ + "managementSystem": "", + "managementSystemId": "", + "createdDate": "2023-05-22T13:47:50.240Z", + "updatedDate": "2023-07-03T07:14:33.794Z", + "archived": false, + "clientClassification": null, + "networkCertificateCa": null, + "adCreationDate": null, + "activeDirectoryOU": null, + "hardwareID": "2f90ced1-1916-45db-b2cf-a6ad66f69aba", + "operatingSystemType": "lnx Red Hat Enterprise Linux release 8.8 (Ootpa)", + "operatingSystem": "8.8", + "operatingSystemInstallDate": null, + "hostName": "client.localhost.localdomain", + "certificateInformation": null, + "networkAccessRole": "None", + "division": null, + "assetOwner": null +} diff --git a/test/test_helper.rb b/test/test_helper.rb index efaf3ddadfc948326ff8f31ab173705d141342ed..1909694d7674f1aaca534fe59f4599b7f614688a 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -6,3 +6,8 @@ $LOAD_PATH.unshift File.expand_path("../lib", __dir__) require "liudesk_cmdb" require "minitest/autorun" +require "webmock/minitest" + +def setup_cmdb_client + LiudeskCMDB::Client.new 'https://example.com', subscription_key: 'testing' +end diff --git a/test/test_v1_models.rb b/test/test_v1_models.rb index ac56576eea7336328213a5123efd037f2d1b540e..a0cdf4027abde9c4ecdea64a55b3ce06758a79d2 100644 --- a/test/test_v1_models.rb +++ b/test/test_v1_models.rb @@ -4,7 +4,7 @@ require "test_helper" class TestV1Models < Minitest::Test def setup - @client = Minitest::Mock.new + @client = setup_cmdb_client end def test_that_hardware_works @@ -19,22 +19,21 @@ class TestV1Models < Minitest::Test assert_raises(NoMethodError) { hardware.created_date = "Something else" } assert_raises(NoMethodError) { hardware.updated_date = "Something else" } - @client.expect( - :post, File.read("test/fixtures/post_hardware.json"), - [ - "liudesk-cmdb/api/Hardware", :v1, - { - "make" => "HP", - "model" => "Elitebook", - "serialNumber" => "abc123", - "purchaseDate" => "2023-06-12T11:58:05.000Z" - } - ] + stub_post = stub_request(:post, "https://example.com/liudesk-cmdb/api/Hardware").with( + body: { + make: "HP", + model: "Elitebook", + serialNumber: "abc123", + purchaseDate: "2023-06-12T11:58:05.000Z" + } + ).to_return( + status: 200, + body: File.read("test/fixtures/post_hardware.json") ) hardware.create - @client.verify + assert_requested stub_post refute hardware.unknown_fields? assert_equal "HP", hardware.make @@ -66,19 +65,18 @@ class TestV1Models < Minitest::Test hardware.supplier = "Dustin" - @client.expect( - :patch, File.read("test/fixtures/post_hardware.json"), - [ - "liudesk-cmdb/api/Hardware/8e2cbcf0-1c79-4b4e-8813-71f8da3c3d81", :v1, - { - "supplier" => "Dustin" - } - ] + stub_patch = stub_request(:patch, "https://example.com/liudesk-cmdb/api/Hardware/8e2cbcf0-1c79-4b4e-8813-71f8da3c3d81").with( + body: { + supplier: "Dustin" + } + ).to_return( + status: 200, + body: File.read("test/fixtures/post_hardware.json") ) hardware.update - @client.verify + assert_requested stub_patch assert_equal "Guest", hardware.network_access_role assert_equal "ATEA", hardware.supplier @@ -87,39 +85,35 @@ class TestV1Models < Minitest::Test assert_equal "Dustin", hardware.supplier - @client.expect( - :get, File.read("test/fixtures/post_hardware.json"), - [ - "liudesk-cmdb/api/Hardware/8e2cbcf0-1c79-4b4e-8813-71f8da3c3d81", :v1 - ] + stub_get = stub_request(:get, "https://example.com/liudesk-cmdb/api/Hardware/8e2cbcf0-1c79-4b4e-8813-71f8da3c3d81").to_return( + status: 200, + body: File.read("test/fixtures/post_hardware.json") ) hardware.refresh - @client.verify + assert_requested stub_get assert_equal "ATEA", hardware.supplier - @client.expect( - :delete, nil, - [ - "liudesk-cmdb/api/Hardware/8e2cbcf0-1c79-4b4e-8813-71f8da3c3d81", :v1 - ] + stub_delete = stub_request(:delete, "https://example.com/liudesk-cmdb/api/Hardware/8e2cbcf0-1c79-4b4e-8813-71f8da3c3d81").to_return( + status: 204, ) hardware.destroy - @client.verify + assert_requested stub_delete - @client.expect(:get, File.read("test/fixtures/search_hardware.json")) do |path, ver, **args| - path == "liudesk-cmdb/api/Hardware/search" && ver == :v1 && args == { query: { - query: "make==HP" - } } - end + stub_get = stub_request(:get, "https://example.com/liudesk-cmdb/api/Hardware/search").with( + query: { query: "make==HP" } + ).to_return( + status: 200, + body: File.read("test/fixtures/search_hardware.json") + ) hardwares = LiudeskCMDB::Models::HardwareV1.search(@client, make: "HP") - @client.verify + assert_requested stub_get hardware = hardwares.first @@ -153,13 +147,14 @@ class TestV1Models < Minitest::Test end def test_that_server_works - @client.expect(:get, File.read("test/fixtures/list_servers.json")) do |path, ver, **args| - path == "liudesk-cmdb/api/Server" && ver == :v1 && args == { query: {} } - end + stub_get = stub_request(:get, "https://example.com/liudesk-cmdb/api/Server").to_return( + status: 200, + body: File.read("test/fixtures/list_servers.json") + ) servers = LiudeskCMDB::Models::ServerV1.list(@client) - @client.verify + assert_requested stub_get server = servers.first @@ -185,16 +180,14 @@ class TestV1Models < Minitest::Test assert_equal Time.parse("2023-04-06T14:15:58Z"), server.created_date assert_equal Time.parse("2023-04-06T14:15:58Z"), server.updated_date - @client.expect( - :get, File.read("test/fixtures/post_hardware.json"), - [ - "liudesk-cmdb/api/Hardware/8e2cbcf0-1c79-4b4e-8813-71f8da3c3d81", :v1 - ] + stub_get = stub_request(:get, "https://example.com/liudesk-cmdb/api/Hardware/8e2cbcf0-1c79-4b4e-8813-71f8da3c3d81").to_return( + status: 200, + body: File.read("test/fixtures/post_hardware.json") ) hardware = server.hardware - @client.verify + assert_requested stub_get refute hardware.unknown_fields? assert_equal "HP", hardware.make @@ -228,17 +221,68 @@ class TestV1Models < Minitest::Test def test_handling_of_unexpected_data server = LiudeskCMDB::Models::ServerV1.new(@client, hostname: 'test.example.com') - @client.expect(:get, '{"hostName":"test.example.com","networkAccessRole":"None","unknownField":"Data"}') do |path, ver, **args| - path == "liudesk-cmdb/api/Server/test.example.com" && ver == :v1 - end + stub_get = stub_request(:get, "https://example.com/liudesk-cmdb/api/Server/test.example.com").to_return( + status: 200, + body: { + hostName: "test.example.com", + networkAccessRole: "None", + unknownField: "Data" + }.to_json + ) assert server.refresh - @client.verify + assert_requested stub_get assert server.unknown_fields? assert_equal "test.example.com", server.hostname assert_equal "None", server.network_access_role assert_equal "Data", server.unknown_fields["unknownField"] end + + def test_handling_of_clients + models = { + LiudeskCMDB::Models::LinuxClientV1 => [ + { + method: :get, + request: :get, + url: 'liudesk-cmdb/api/Clients/linux/%<identifier>s', + body: 'test/fixtures/get_linuxclient.json' + } + ], + LiudeskCMDB::Models::MacClientV1 => [ + ], + LiudeskCMDB::Models::WindowsClientV1 => [ + ], + LiudeskCMDB::Models::LinuxComputerlabV1 => [ + ], + # LiudeskCMDB::Models::MacComputerlabV1, + LiudeskCMDB::Models::WindowsComputerlabV1 => [ + ], + } + + identifier = "client.localhost.localdomain" + models.each do |klass, requests| + instance = klass.new(@client, identifier) + + assert instance + + requests.each do |req| + stub = stub_request(req[:request], "https://example.com/#{req[:url] % { identifier: identifier }}").to_return( + status: req.fetch(:status, 200), + body: req.fetch(:body_data, File.read(req[:body])) + ) + + result = nil + case req[:method] + when :get + result = klass.get(@client, identifier) + end + + assert_requested stub + + assert result unless req[:method] == :delete + end + end + end end