foreman_netbox 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +619 -0
  3. data/README.md +50 -0
  4. data/Rakefile +50 -0
  5. data/app/contracts/foreman_netbox/device_contract.rb +42 -0
  6. data/app/contracts/foreman_netbox/params/interface_params.rb +16 -0
  7. data/app/contracts/foreman_netbox/params/ip_address_params.rb +15 -0
  8. data/app/contracts/foreman_netbox/params/tenant_params.rb +13 -0
  9. data/app/contracts/foreman_netbox/virtual_machine_contract.rb +29 -0
  10. data/app/interactors/foreman_netbox/concerns/facts.rb +11 -0
  11. data/app/interactors/foreman_netbox/concerns/primary_ips.rb +25 -0
  12. data/app/interactors/foreman_netbox/delete_host/delete_device.rb +20 -0
  13. data/app/interactors/foreman_netbox/delete_host/delete_virtual_machine.rb +20 -0
  14. data/app/interactors/foreman_netbox/delete_host/organizer.rb +12 -0
  15. data/app/interactors/foreman_netbox/sync_host/organizer.rb +35 -0
  16. data/app/interactors/foreman_netbox/sync_host/sync_device/create.rb +36 -0
  17. data/app/interactors/foreman_netbox/sync_host/sync_device/find.rb +41 -0
  18. data/app/interactors/foreman_netbox/sync_host/sync_device/organizer.rb +30 -0
  19. data/app/interactors/foreman_netbox/sync_host/sync_device/save_netbox_url.rb +29 -0
  20. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_device_role/create.rb +32 -0
  21. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_device_role/find.rb +28 -0
  22. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_device_role/organizer.rb +20 -0
  23. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_device_type/create.rb +34 -0
  24. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_device_type/find.rb +28 -0
  25. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_device_type/organizer.rb +22 -0
  26. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_device_type/sync_manufacturer/create.rb +34 -0
  27. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_device_type/sync_manufacturer/find.rb +40 -0
  28. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_device_type/sync_manufacturer/organizer.rb +22 -0
  29. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_device_type/update.rb +33 -0
  30. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/create.rb +37 -0
  31. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/delete.rb +36 -0
  32. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/find.rb +30 -0
  33. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/organizer.rb +23 -0
  34. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/sync_ip_addresses/create.rb +46 -0
  35. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/sync_ip_addresses/delete.rb +40 -0
  36. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/sync_ip_addresses/find.rb +32 -0
  37. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/sync_ip_addresses/organizer.rb +24 -0
  38. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/sync_ip_addresses/update.rb +39 -0
  39. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/update.rb +38 -0
  40. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_site/create.rb +32 -0
  41. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_site/find.rb +28 -0
  42. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_site/organizer.rb +25 -0
  43. data/app/interactors/foreman_netbox/sync_host/sync_device/sync_site/update.rb +35 -0
  44. data/app/interactors/foreman_netbox/sync_host/sync_device/update.rb +85 -0
  45. data/app/interactors/foreman_netbox/sync_host/sync_device/validate.rb +25 -0
  46. data/app/interactors/foreman_netbox/sync_host/sync_tenant/create.rb +30 -0
  47. data/app/interactors/foreman_netbox/sync_host/sync_tenant/find.rb +26 -0
  48. data/app/interactors/foreman_netbox/sync_host/sync_tenant/organizer.rb +19 -0
  49. data/app/interactors/foreman_netbox/sync_host/sync_tenant/update.rb +33 -0
  50. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/create.rb +34 -0
  51. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/find.rb +34 -0
  52. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/organizer.rb +28 -0
  53. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/save_netbox_url.rb +31 -0
  54. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_cluster/create.rb +35 -0
  55. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_cluster/find.rb +28 -0
  56. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_cluster/organizer.rb +22 -0
  57. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_cluster/sync_cluster_type/create.rb +34 -0
  58. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_cluster/sync_cluster_type/find.rb +32 -0
  59. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_cluster/sync_cluster_type/organizer.rb +22 -0
  60. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_cluster/update.rb +35 -0
  61. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/create.rb +33 -0
  62. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/delete.rb +36 -0
  63. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/find.rb +30 -0
  64. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/organizer.rb +23 -0
  65. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/sync_ip_addresses/create.rb +46 -0
  66. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/sync_ip_addresses/delete.rb +40 -0
  67. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/sync_ip_addresses/find.rb +28 -0
  68. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/sync_ip_addresses/organizer.rb +24 -0
  69. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/sync_ip_addresses/update.rb +39 -0
  70. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/update.rb +38 -0
  71. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/update.rb +82 -0
  72. data/app/interactors/foreman_netbox/sync_host/sync_virtual_machine/validate.rb +25 -0
  73. data/app/jobs/foreman_netbox/sync_host_job.rb +19 -0
  74. data/app/lib/foreman_netbox/api.rb +12 -0
  75. data/app/models/concerns/foreman_netbox/host_extensions.rb +27 -0
  76. data/app/models/concerns/foreman_netbox/location_extensions.rb +13 -0
  77. data/app/models/concerns/foreman_netbox/nic/base_extensions.rb +23 -0
  78. data/app/models/concerns/foreman_netbox/user_usergroup_common_extensions.rb +18 -0
  79. data/app/models/foreman_netbox/netbox_facet.rb +34 -0
  80. data/app/models/orchestration/netbox.rb +64 -0
  81. data/app/models/setting/netbox.rb +32 -0
  82. data/app/services/foreman_netbox/cached_netbox_parameters.rb +103 -0
  83. data/app/services/foreman_netbox/netbox_parameters.rb +185 -0
  84. data/app/services/foreman_netbox/netbox_parameters_comparator.rb +96 -0
  85. data/app/views/hosts/_netbox_tab.html.erb +28 -0
  86. data/config/routes.rb +4 -0
  87. data/db/migrate/20200527135812_create_netbox_facet.rb +12 -0
  88. data/db/migrate/20200604141933_add_sync_info_to_netbox_facet.rb +8 -0
  89. data/db/migrate/20200708093607_add_raw_data_to_netbox_facet.rb +7 -0
  90. data/lib/foreman_netbox.rb +6 -0
  91. data/lib/foreman_netbox/engine.rb +64 -0
  92. data/lib/foreman_netbox/version.rb +5 -0
  93. data/lib/tasks/foreman_netbox_tasks.rake +67 -0
  94. data/test/factories/host.rb +17 -0
  95. data/test/factories/netbox_facet.rb +17 -0
  96. data/test/fixtures/facts/k8s_physical_host.json +328 -0
  97. data/test/fixtures/facts/rhel_physical_host.json +512 -0
  98. data/test/fixtures/facts/rhel_virtual_host.json +455 -0
  99. data/test/fixtures/netbox_device_raw_data.json +330 -0
  100. data/test/fixtures/netbox_virtual_machine_raw_data.json +241 -0
  101. data/test/integration/foreman_netbox/sync_k8s_physical_host_test.rb +81 -0
  102. data/test/integration/foreman_netbox/sync_rhel_physical_host_test.rb +81 -0
  103. data/test/integration/foreman_netbox/sync_rhel_virtual_host_test.rb +93 -0
  104. data/test/interactors/foreman_netbox/sync_host/organizer_test.rb +78 -0
  105. data/test/interactors/foreman_netbox/sync_host/sync_device/create_test.rb +65 -0
  106. data/test/interactors/foreman_netbox/sync_host/sync_device/find_test.rb +105 -0
  107. data/test/interactors/foreman_netbox/sync_host/sync_device/save_netbox_url_test.rb +39 -0
  108. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_device_role/create_test.rb +45 -0
  109. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_device_role/find_test.rb +58 -0
  110. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_device_type/create_test.rb +55 -0
  111. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_device_type/find_test.rb +63 -0
  112. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_device_type/sync_manufacturer/create_test.rb +48 -0
  113. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_device_type/sync_manufacturer/find_test.rb +105 -0
  114. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_device_type/update_test.rb +54 -0
  115. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/create_test.rb +51 -0
  116. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/delete_test.rb +41 -0
  117. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/find_test.rb +53 -0
  118. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/sync_ip_addresses/create_test.rb +80 -0
  119. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/sync_ip_addresses/delete_test.rb +72 -0
  120. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/sync_ip_addresses/find_test.rb +51 -0
  121. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/sync_ip_addresses/update_test.rb +64 -0
  122. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_interfaces/update_test.rb +92 -0
  123. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_site/create_test.rb +51 -0
  124. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_site/find_test.rb +59 -0
  125. data/test/interactors/foreman_netbox/sync_host/sync_device/sync_site/update_test.rb +54 -0
  126. data/test/interactors/foreman_netbox/sync_host/sync_device/update_test.rb +188 -0
  127. data/test/interactors/foreman_netbox/sync_host/sync_tenant/create_test.rb +50 -0
  128. data/test/interactors/foreman_netbox/sync_host/sync_tenant/find_test.rb +58 -0
  129. data/test/interactors/foreman_netbox/sync_host/sync_tenant/update_test.rb +59 -0
  130. data/test/interactors/foreman_netbox/sync_host/sync_virtual_machine/create_test.rb +74 -0
  131. data/test/interactors/foreman_netbox/sync_host/sync_virtual_machine/find_test.rb +77 -0
  132. data/test/interactors/foreman_netbox/sync_host/sync_virtual_machine/save_netbox_url_test.rb +39 -0
  133. data/test/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_cluster/create_test.rb +54 -0
  134. data/test/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_cluster/find_test.rb +58 -0
  135. data/test/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_cluster/sync_cluster_type/create_test.rb +50 -0
  136. data/test/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_cluster/sync_cluster_type/find_test.rb +65 -0
  137. data/test/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_cluster/update_test.rb +54 -0
  138. data/test/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/create_test.rb +53 -0
  139. data/test/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/delete_test.rb +37 -0
  140. data/test/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/find_test.rb +53 -0
  141. data/test/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/sync_ip_addresses/create_test.rb +80 -0
  142. data/test/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/sync_ip_addresses/delete_test.rb +73 -0
  143. data/test/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/sync_ip_addresses/find_test.rb +51 -0
  144. data/test/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/sync_ip_addresses/update_test.rb +64 -0
  145. data/test/interactors/foreman_netbox/sync_host/sync_virtual_machine/sync_interfaces/update_test.rb +88 -0
  146. data/test/interactors/foreman_netbox/sync_host/sync_virtual_machine/update_test.rb +171 -0
  147. data/test/jobs/foreman_netbox/sync_host_job_test.rb +14 -0
  148. data/test/models/foreman_netbox/location_test.rb +42 -0
  149. data/test/models/foreman_netbox/netbox_facet_test.rb +219 -0
  150. data/test/models/foreman_netbox/nics/base_test.rb +81 -0
  151. data/test/models/foreman_netbox/usergroup_test.rb +23 -0
  152. data/test/models/host/managed_test.rb +63 -0
  153. data/test/services/foreman_netbox/netbox_attributes_test.rb +278 -0
  154. data/test/services/foreman_netbox/netbox_parameters_comparator_test.rb +136 -0
  155. data/test/test_plugin_helper.rb +25 -0
  156. metadata +343 -0
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_plugin_helper'
4
+
5
+ class CreateDeviceInterfacesTest < ActiveSupport::TestCase
6
+ subject do
7
+ ForemanNetbox::SyncHost::SyncDevice::SyncInterfaces::Create.call(
8
+ host: host, netbox_params: host.netbox_facet.netbox_params, device: device, interfaces: interfaces
9
+ )
10
+ end
11
+
12
+ let(:interfaces) { [OpenStruct.new(name: host.interfaces.second.netbox_name)] }
13
+ let(:device) { OpenStruct.new(id: 1) }
14
+ let(:host) do
15
+ FactoryBot.build_stubbed(
16
+ :host,
17
+ interfaces: [
18
+ FactoryBot.build_stubbed(:nic_base, mac: 'FE:13:C6:44:29:24', ip: '10.0.0.1', ip6: '1500:0:2d0:201::1'),
19
+ FactoryBot.build_stubbed(:nic_base, mac: 'FE:13:C6:44:29:22', ip: '10.0.0.2', ip6: '1500:0:2d0:201::2'),
20
+ FactoryBot.build_stubbed(:nic_base, identifier: nil, mac: nil)
21
+ ]
22
+ )
23
+ end
24
+
25
+ setup do
26
+ setup_default_netbox_settings
27
+ end
28
+
29
+ it 'creates missing interfaces' do
30
+ interfaces.expects(:reload).once.returns(true)
31
+
32
+ stub_post = stub_request(:post, "#{Setting[:netbox_url]}/api/dcim/interfaces/").with(
33
+ body: {
34
+ name: host.interfaces.first.netbox_name,
35
+ mac_address: host.interfaces.first.mac,
36
+ tags: ForemanNetbox::NetboxParameters::DEFAULT_TAGS,
37
+ type: ForemanNetbox::NetboxParameters::DEFAULT_INTERFACE_TYPE,
38
+ device: device.id
39
+ }.to_json
40
+ ).to_return(
41
+ status: 201, headers: { 'Content-Type': 'application/json' },
42
+ body: {
43
+ id: 1,
44
+ name: host.interfaces.first.netbox_name
45
+ }.to_json
46
+ )
47
+
48
+ subject
49
+ assert_requested(stub_post)
50
+ end
51
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_plugin_helper'
4
+
5
+ class DeleteDeviceInterfacesTest < ActiveSupport::TestCase
6
+ subject do
7
+ ForemanNetbox::SyncHost::SyncDevice::SyncInterfaces::Delete.call(
8
+ host: host,
9
+ netbox_params: host.netbox_facet.netbox_params,
10
+ interfaces: interfaces
11
+ )
12
+ end
13
+
14
+ let(:interface_id) { 1 }
15
+ let(:interfaces) { ForemanNetbox::API.client::DCIM::Interfaces.new }
16
+ let(:host) do
17
+ FactoryBot.build_stubbed(:host, interfaces: [])
18
+ end
19
+
20
+ setup do
21
+ setup_default_netbox_settings
22
+ stub_request(:get, "#{Setting[:netbox_url]}/api/dcim/interfaces.json").with(
23
+ query: { limit: 50 }
24
+ ).to_return(
25
+ status: 200, headers: { 'Content-Type': 'application/json' },
26
+ body: {
27
+ count: 1,
28
+ results: [{ id: interface_id, name: 'eth0' }]
29
+ }.to_json
30
+ )
31
+ end
32
+
33
+ it 'deletes interfaces that are not assigned to the host' do
34
+ stub_delete = stub_request(:delete, "#{Setting[:netbox_url]}/api/dcim/interfaces/#{interface_id}.json").to_return(
35
+ status: 200
36
+ )
37
+
38
+ subject
39
+ assert_requested(stub_delete)
40
+ end
41
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_plugin_helper'
4
+
5
+ class FindDeviceInterfacesTest < ActiveSupport::TestCase
6
+ subject do
7
+ ForemanNetbox::SyncHost::SyncDevice::SyncInterfaces::Find.call(
8
+ device: device
9
+ )
10
+ end
11
+
12
+ let(:device) { OpenStruct.new(id: 1) }
13
+
14
+ setup do
15
+ setup_default_netbox_settings
16
+ end
17
+
18
+ context 'when interfaces were found on Netbox' do
19
+ it 'assigns interfaces to context' do
20
+ stub_get = stub_request(:get, "#{Setting[:netbox_url]}/api/dcim/interfaces.json").with(
21
+ query: { limit: 50, device_id: device.id }
22
+ ).to_return(
23
+ status: 200, headers: { 'Content-Type': 'application/json' },
24
+ body: {
25
+ count: 1,
26
+ results: [
27
+ { id: 1 }
28
+ ]
29
+ }.to_json
30
+ )
31
+
32
+ assert_equal [1], subject.interfaces.map(&:id)
33
+ assert_requested(stub_get)
34
+ end
35
+ end
36
+
37
+ context 'when interfaces were not found on Netbox' do
38
+ it 'does not assign interfaces to context' do
39
+ stub_get = stub_request(:get, "#{Setting[:netbox_url]}/api/dcim/interfaces.json").with(
40
+ query: { limit: 50, device_id: device.id }
41
+ ).to_return(
42
+ status: 200, headers: { 'Content-Type': 'application/json' },
43
+ body: {
44
+ count: 0,
45
+ results: []
46
+ }.to_json
47
+ )
48
+
49
+ assert_equal [], subject.interfaces.map(&:id)
50
+ assert_requested(stub_get)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_plugin_helper'
4
+
5
+ class CreateDeviceIpAddressesTest < ActiveSupport::TestCase
6
+ subject do
7
+ ForemanNetbox::SyncHost::SyncDevice::SyncInterfaces::SyncIpAddresses::Create.call(
8
+ host: host, interfaces: interfaces, netbox_params: host.netbox_facet.netbox_params
9
+ )
10
+ end
11
+
12
+ let(:interfaces) { [OpenStruct.new(id: 1, name: host.interfaces.first.netbox_name)] }
13
+ let(:subnet) { FactoryBot.build_stubbed(:subnet_ipv4) }
14
+ let(:subnet6) { FactoryBot.build_stubbed(:subnet_ipv6) }
15
+ let(:host) do
16
+ FactoryBot.build_stubbed(
17
+ :host,
18
+ interfaces: [
19
+ FactoryBot.build_stubbed(
20
+ :nic_base,
21
+ mac: 'FE:13:C6:44:29:24',
22
+ ip: '10.0.0.1',
23
+ ip6: '1500:0:2d0:201::1',
24
+ subnet: subnet,
25
+ subnet6: subnet6
26
+ )
27
+ ]
28
+ )
29
+ end
30
+
31
+ setup do
32
+ setup_default_netbox_settings
33
+ stub_request(:get, "#{Setting[:netbox_url]}/api/ipam/ip-addresses.json").with(
34
+ query: { limit: 50, interface_id: interfaces.first.id, address: host.interfaces.first.netbox_ip }
35
+ ).to_return(
36
+ status: 200, headers: { 'Content-Type': 'application/json' },
37
+ body: {
38
+ count: 0,
39
+ results: []
40
+ }.to_json
41
+ )
42
+ stub_request(:get, "#{Setting[:netbox_url]}/api/ipam/ip-addresses.json").with(
43
+ query: { limit: 50, interface_id: interfaces.first.id, address: host.interfaces.first.netbox_ip6 }
44
+ ).to_return(
45
+ status: 200, headers: { 'Content-Type': 'application/json' },
46
+ body: {
47
+ count: 1,
48
+ results: [{ id: 2 }]
49
+ }.to_json
50
+ )
51
+ end
52
+
53
+ it 'creates missing IP addresses in Netbox' do
54
+ stub_post_ip_address_v4 = stub_request(:post, "#{Setting[:netbox_url]}/api/ipam/ip-addresses/").with(
55
+ body: {
56
+ address: host.interfaces.first.netbox_ip,
57
+ tags: ForemanNetbox::NetboxParameters::DEFAULT_TAGS,
58
+ interface: interfaces.first.id
59
+ }.to_json
60
+ ).to_return(
61
+ status: 201, headers: { 'Content-Type': 'application/json' },
62
+ body: { id: 1 }.to_json
63
+ )
64
+
65
+ stub_post_ip_address_v6 = stub_request(:post, "#{Setting[:netbox_url]}/api/ipam/ip-addresses/").with(
66
+ body: {
67
+ address: host.interfaces.first.netbox_ip6,
68
+ tags: ForemanNetbox::NetboxParameters::DEFAULT_TAGS,
69
+ interface: interfaces.first.id
70
+ }.to_json
71
+ ).to_return(
72
+ status: 201, headers: { 'Content-Type': 'application/json' },
73
+ body: { id: 1 }.to_json
74
+ )
75
+
76
+ subject
77
+ assert_requested(stub_post_ip_address_v4)
78
+ assert_not_requested(stub_post_ip_address_v6)
79
+ end
80
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_plugin_helper'
4
+
5
+ class DeleteDeviceIpAddressesTest < ActiveSupport::TestCase
6
+ subject do
7
+ ForemanNetbox::SyncHost::SyncDevice::SyncInterfaces::SyncIpAddresses::Delete.call(
8
+ host: host, interfaces: interfaces, ip_addresses: ip_addresses, netbox_params: host.netbox_facet.netbox_params
9
+ )
10
+ end
11
+
12
+ let(:interfaces) { ForemanNetbox::API.client.dcim.interfaces.filter(device_id: 1) }
13
+ let(:ip_addresses) { ForemanNetbox::API.client.ipam.ip_addresses.filter(device_id: 1) }
14
+ let(:host) do
15
+ FactoryBot.build_stubbed(
16
+ :host,
17
+ interfaces: [
18
+ FactoryBot.build_stubbed(
19
+ :nic_base,
20
+ ip: '10.0.0.1',
21
+ subnet: FactoryBot.build_stubbed(:subnet_ipv4)
22
+ )
23
+ ]
24
+ )
25
+ end
26
+
27
+ let(:interface_id) { 1 }
28
+ let(:ip_addresses_v4_id) { 1 }
29
+ let(:ip_addresses_v6_id) { 2 }
30
+ let(:ip_addresses_v4) { host.interfaces.first.netbox_ip }
31
+ let(:ip_addresses_v6) { '1500:0:2d0:201::1/32' }
32
+
33
+ setup do
34
+ setup_default_netbox_settings
35
+ stub_request(:get, "#{Setting[:netbox_url]}/api/dcim/interfaces.json").with(
36
+ query: { limit: 50, device_id: 1 }
37
+ ).to_return(
38
+ status: 200, headers: { 'Content-Type': 'application/json' },
39
+ body: {
40
+ count: 1,
41
+ results: [
42
+ { id: interface_id, name: host.interfaces.first.netbox_name }
43
+ ]
44
+ }.to_json
45
+ )
46
+ stub_request(:get, "#{Setting[:netbox_url]}/api/ipam/ip-addresses.json").with(
47
+ query: { limit: 50, device_id: 1 }
48
+ ).to_return(
49
+ status: 200, headers: { 'Content-Type': 'application/json' },
50
+ body: {
51
+ count: 2,
52
+ results: [
53
+ { id: ip_addresses_v4_id, address: ip_addresses_v4, interface: { id: interface_id } },
54
+ { id: ip_addresses_v6_id, address: ip_addresses_v6, interface: { id: interface_id } }
55
+ ]
56
+ }.to_json
57
+ )
58
+ end
59
+
60
+ it 'deletes from Netbox IP addresses that are not assigned to the host' do
61
+ stub_delete_ip_address_v4 = stub_request(:delete, "#{Setting[:netbox_url]}/api/ipam/ip-addresses/#{ip_addresses_v4_id}.json").to_return(
62
+ status: 200, headers: { 'Content-Type': 'application/json' }
63
+ )
64
+ stub_delete_ip_address_v6 = stub_request(:delete, "#{Setting[:netbox_url]}/api/ipam/ip-addresses/#{ip_addresses_v6_id}.json").to_return(
65
+ status: 200, headers: { 'Content-Type': 'application/json' }
66
+ )
67
+
68
+ subject
69
+ assert_not_requested(stub_delete_ip_address_v4)
70
+ assert_requested(stub_delete_ip_address_v6)
71
+ end
72
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_plugin_helper'
4
+
5
+ class FindDeviceIpAddressesTest < ActiveSupport::TestCase
6
+ subject do
7
+ ForemanNetbox::SyncHost::SyncDevice::SyncInterfaces::SyncIpAddresses::Find.call(
8
+ device: device
9
+ )
10
+ end
11
+
12
+ let(:device) { OpenStruct.new(id: 1) }
13
+
14
+ setup do
15
+ setup_default_netbox_settings
16
+ end
17
+
18
+ context 'when ip_addresses were found on Netbox' do
19
+ it 'assigns ip_addresses to context' do
20
+ stub_get = stub_request(:get, "#{Setting[:netbox_url]}/api/ipam/ip-addresses.json").with(
21
+ query: { limit: 50, device_id: device.id }
22
+ ).to_return(
23
+ status: 200, headers: { 'Content-Type': 'application/json' },
24
+ body: {
25
+ count: 1,
26
+ results: [{ id: 1 }]
27
+ }.to_json
28
+ )
29
+
30
+ assert_equal [1], subject.ip_addresses.map(&:id)
31
+ assert_requested(stub_get)
32
+ end
33
+ end
34
+
35
+ context 'when ip_addresses were not found on Netbox' do
36
+ it 'does not assign ip_addresses to context' do
37
+ stub_get = stub_request(:get, "#{Setting[:netbox_url]}/api/ipam/ip-addresses.json").with(
38
+ query: { limit: 50, device_id: device.id }
39
+ ).to_return(
40
+ status: 200, headers: { 'Content-Type': 'application/json' },
41
+ body: {
42
+ count: 0,
43
+ results: []
44
+ }.to_json
45
+ )
46
+
47
+ assert_equal [], subject.ip_addresses.map(&:id)
48
+ assert_requested(stub_get)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_plugin_helper'
4
+
5
+ class UpdateDeviceIpAddressesTest < ActiveSupport::TestCase
6
+ subject do
7
+ ForemanNetbox::SyncHost::SyncDevice::SyncInterfaces::SyncIpAddresses::Update.call(
8
+ ip_addresses: ip_addresses,
9
+ netbox_params: host.netbox_facet.netbox_params
10
+ )
11
+ end
12
+
13
+ let(:ip_addresses) { ForemanNetbox::API.client.ipam.ip_addresses.filter(device_id: 1) }
14
+ let(:ip_addresses_data) do
15
+ [
16
+ { id: 1, address: host.netbox_facet.netbox_params[:ip_addresses].first[:address], tags: ForemanNetbox::NetboxParameters::DEFAULT_TAGS },
17
+ { id: 2, address: host.netbox_facet.netbox_params[:ip_addresses].second[:address], tags: [] }
18
+ ]
19
+ end
20
+ let(:host) do
21
+ FactoryBot.build_stubbed(
22
+ :host,
23
+ interfaces: [
24
+ FactoryBot.build_stubbed(
25
+ :nic_base,
26
+ identifier: 'eth0',
27
+ ip: '10.0.0.7',
28
+ ip6: '1600:0:2d0:202::17',
29
+ subnet: FactoryBot.build_stubbed(:subnet_ipv4, organizations: [], locations: []),
30
+ subnet6: FactoryBot.build_stubbed(:subnet_ipv6, organizations: [], locations: [])
31
+ )
32
+ ]
33
+ )
34
+ end
35
+
36
+ setup do
37
+ setup_default_netbox_settings
38
+ stub_request(:get, "#{Setting[:netbox_url]}/api/ipam/ip-addresses.json").with(
39
+ query: { limit: 50, device_id: 1 }
40
+ ).to_return(
41
+ status: 200, headers: { 'Content-Type': 'application/json' },
42
+ body: {
43
+ count: ip_addresses_data.count,
44
+ results: ip_addresses_data
45
+ }.to_json
46
+ )
47
+ end
48
+
49
+ test 'update ip addresses' do
50
+ stub_unexpected_patch = stub_request(:patch, "#{Setting[:netbox_url]}/api/ipam/ip-addresses/#{ip_addresses_data.first[:id]}.json")
51
+ stub_expected_patch = stub_request(:patch, "#{Setting[:netbox_url]}/api/ipam/ip-addresses/#{ip_addresses_data.second[:id]}.json").with(
52
+ body: {
53
+ tags: ForemanNetbox::NetboxParameters::DEFAULT_TAGS
54
+ }.to_json
55
+ ).to_return(
56
+ status: 200, headers: { 'Content-Type': 'application/json' },
57
+ body: { id: 2 }.to_json
58
+ )
59
+
60
+ assert subject.success?
61
+ assert_not_requested stub_unexpected_patch
62
+ assert_requested stub_expected_patch
63
+ end
64
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_plugin_helper'
4
+
5
+ class UpdateDeviceInterfacesTest < ActiveSupport::TestCase
6
+ subject do
7
+ ForemanNetbox::SyncHost::SyncDevice::SyncInterfaces::Update.call(
8
+ interfaces: interfaces,
9
+ host: host,
10
+ netbox_params: host.netbox_facet.netbox_params
11
+ )
12
+ end
13
+
14
+ let(:interfaces) { ForemanNetbox::API.client::DCIM::Interfaces.new }
15
+ let(:old_mac) { 'FE:13:C6:44:29:22' }
16
+ let(:host) do
17
+ FactoryBot.build_stubbed(
18
+ :host,
19
+ interfaces: [
20
+ FactoryBot.build_stubbed(
21
+ :nic_base,
22
+ identifier: 'eth1',
23
+ mac: old_mac
24
+ )
25
+ ]
26
+ )
27
+ end
28
+
29
+ setup do
30
+ setup_default_netbox_settings
31
+ end
32
+
33
+ context 'if the interface has been updated since the last synchronization' do
34
+ let(:new_mac) { 'FE:13:C6:44:29:24' }
35
+
36
+ it 'updats interface in Netbox' do
37
+ get_stub = stub_request(:get, "#{Setting[:netbox_url]}/api/dcim/interfaces.json").with(
38
+ query: { limit: 50 }
39
+ ).to_return(
40
+ status: 200, headers: { 'Content-Type': 'application/json' },
41
+ body: {
42
+ count: 1,
43
+ results: [
44
+ {
45
+ id: 1,
46
+ name: host.interfaces.first.netbox_name,
47
+ mac_address: new_mac,
48
+ tags: []
49
+ }
50
+ ]
51
+ }.to_json
52
+ )
53
+ stub_patch = stub_request(:patch, "#{Setting[:netbox_url]}/api/dcim/interfaces/1.json").with(
54
+ body: {
55
+ mac_address: host.interfaces.first.mac,
56
+ tags: ForemanNetbox::NetboxParameters::DEFAULT_TAGS
57
+ }.to_json
58
+ ).to_return(
59
+ status: 200, headers: { 'Content-Type': 'application/json' },
60
+ body: { id: 1 }.to_json
61
+ )
62
+
63
+ subject
64
+ assert_requested(get_stub)
65
+ assert_requested(stub_patch)
66
+ end
67
+ end
68
+
69
+ context 'if the host has not been updated since the last synchronization' do
70
+ it 'does not update interface on Netbox' do
71
+ get_stub = stub_request(:get, "#{Setting[:netbox_url]}/api/dcim/interfaces.json").with(
72
+ query: { limit: 50 }
73
+ ).to_return(
74
+ status: 200, headers: { 'Content-Type': 'application/json' },
75
+ body: {
76
+ count: 1,
77
+ results: [
78
+ {
79
+ id: 1,
80
+ name: host.interfaces.first.netbox_name,
81
+ mac_address: old_mac,
82
+ tags: ForemanNetbox::NetboxParameters::DEFAULT_TAGS
83
+ }
84
+ ]
85
+ }.to_json
86
+ )
87
+
88
+ subject
89
+ assert_requested(get_stub)
90
+ end
91
+ end
92
+ end