fog-hyperv 0.0.9 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -2
  3. data/lib/fog/bin/hyperv.rb +6 -4
  4. data/lib/fog/hyperv/collection.rb +89 -0
  5. data/lib/fog/hyperv/compute/models/bios.rb +70 -0
  6. data/lib/fog/hyperv/compute/models/cluster.rb +60 -0
  7. data/lib/fog/hyperv/compute/models/clusters.rb +21 -0
  8. data/lib/fog/hyperv/compute/models/com_port.rb +78 -0
  9. data/lib/fog/hyperv/compute/models/com_ports.rb +29 -0
  10. data/lib/fog/hyperv/compute/models/dvd_drive.rb +126 -0
  11. data/lib/fog/hyperv/compute/models/dvd_drives.rb +29 -0
  12. data/lib/fog/hyperv/compute/models/firmware.rb +78 -0
  13. data/lib/fog/hyperv/compute/models/floppy_drive.rb +64 -0
  14. data/lib/fog/hyperv/compute/models/floppy_drives.rb +18 -0
  15. data/lib/fog/hyperv/compute/models/hard_drive.rb +187 -0
  16. data/lib/fog/hyperv/compute/models/hard_drives.rb +28 -0
  17. data/lib/fog/hyperv/compute/models/host.rb +66 -0
  18. data/lib/fog/hyperv/compute/models/hosts.rb +13 -0
  19. data/lib/fog/hyperv/compute/models/network_adapter.rb +362 -0
  20. data/lib/fog/hyperv/compute/models/network_adapter_vlan.rb +172 -0
  21. data/lib/fog/hyperv/compute/models/network_adapters.rb +32 -0
  22. data/lib/fog/hyperv/compute/models/security.rb +121 -0
  23. data/lib/fog/hyperv/compute/models/server.rb +466 -0
  24. data/lib/fog/hyperv/compute/models/servers.rb +18 -0
  25. data/lib/fog/hyperv/compute/models/switch.rb +117 -0
  26. data/lib/fog/hyperv/compute/models/switches.rb +20 -0
  27. data/lib/fog/hyperv/compute/models/vhd.rb +210 -0
  28. data/lib/fog/hyperv/compute/models/vhds.rb +28 -0
  29. data/lib/fog/hyperv/compute/requests/add_vm_dvd_drive.rb +15 -0
  30. data/lib/fog/hyperv/compute/requests/add_vm_hard_disk_drive.rb +15 -0
  31. data/lib/fog/hyperv/compute/requests/add_vm_network_adapter.rb +24 -0
  32. data/lib/fog/hyperv/compute/requests/connect_vm_network_adapter.rb +41 -0
  33. data/lib/fog/hyperv/compute/requests/disable_vm_tpm.rb +16 -0
  34. data/lib/fog/hyperv/compute/requests/disconnect_vm_network_adapter.rb +29 -0
  35. data/lib/fog/hyperv/compute/requests/enable_vm_tpm.rb +16 -0
  36. data/lib/fog/hyperv/compute/requests/get_cluster.rb +11 -0
  37. data/lib/fog/hyperv/compute/requests/get_cluster_node.rb +22 -0
  38. data/lib/fog/hyperv/compute/requests/get_vhd.rb +32 -0
  39. data/lib/fog/hyperv/compute/requests/get_vm.rb +18 -0
  40. data/lib/fog/hyperv/compute/requests/get_vm_bios.rb +21 -0
  41. data/lib/fog/hyperv/compute/requests/get_vm_com_port.rb +17 -0
  42. data/lib/fog/hyperv/compute/requests/get_vm_dvd_drive.rb +25 -0
  43. data/lib/fog/hyperv/compute/requests/get_vm_firmware.rb +21 -0
  44. data/lib/fog/hyperv/compute/requests/get_vm_floppy_disk_drive.rb +16 -0
  45. data/lib/fog/hyperv/compute/requests/get_vm_group.rb +20 -0
  46. data/lib/fog/hyperv/compute/requests/get_vm_hard_disk_drive.rb +24 -0
  47. data/lib/fog/hyperv/compute/requests/get_vm_host.rb +9 -0
  48. data/lib/fog/hyperv/compute/requests/get_vm_host_cluster.rb +21 -0
  49. data/lib/fog/hyperv/compute/requests/get_vm_host_sbt.rb +10 -0
  50. data/lib/fog/hyperv/compute/requests/get_vm_key_protector.rb +16 -0
  51. data/lib/fog/hyperv/compute/requests/get_vm_network_adapter.rb +41 -0
  52. data/lib/fog/hyperv/compute/requests/get_vm_network_adapter_vlan.rb +41 -0
  53. data/lib/fog/hyperv/compute/requests/get_vm_security.rb +15 -0
  54. data/lib/fog/hyperv/compute/requests/get_vm_switch.rb +10 -0
  55. data/lib/fog/hyperv/compute/requests/mock_files/get_vm.json +4 -0
  56. data/lib/fog/hyperv/compute/requests/new_vhd.rb +9 -0
  57. data/lib/fog/hyperv/compute/requests/new_vm.rb +12 -0
  58. data/lib/fog/hyperv/compute/requests/new_vm_switch.rb +11 -0
  59. data/lib/fog/hyperv/compute/requests/optimize_vhd.rb +9 -0
  60. data/lib/fog/hyperv/compute/requests/remove_item.rb +10 -0
  61. data/lib/fog/hyperv/compute/requests/remove_vm.rb +16 -0
  62. data/lib/fog/hyperv/compute/requests/remove_vm_dvd_drive.rb +17 -0
  63. data/lib/fog/hyperv/compute/requests/remove_vm_hard_disk_drive.rb +17 -0
  64. data/lib/fog/hyperv/compute/requests/remove_vm_network_adapter.rb +29 -0
  65. data/lib/fog/hyperv/compute/requests/remove_vm_switch.rb +9 -0
  66. data/lib/fog/hyperv/compute/requests/rename_vm.rb +16 -0
  67. data/lib/fog/hyperv/compute/requests/rename_vm_network_adapter.rb +25 -0
  68. data/lib/fog/hyperv/compute/requests/rename_vm_switch.rb +9 -0
  69. data/lib/fog/hyperv/compute/requests/resize_vhd.rb +9 -0
  70. data/lib/fog/hyperv/compute/requests/restart_vm.rb +22 -0
  71. data/lib/fog/hyperv/compute/requests/resume_vm.rb +22 -0
  72. data/lib/fog/hyperv/compute/requests/save_vm.rb +22 -0
  73. data/lib/fog/hyperv/compute/requests/set_vm.rb +15 -0
  74. data/lib/fog/hyperv/compute/requests/set_vm_bios.rb +15 -0
  75. data/lib/fog/hyperv/compute/requests/set_vm_com_port.rb +16 -0
  76. data/lib/fog/hyperv/compute/requests/set_vm_dvd_drive.rb +16 -0
  77. data/lib/fog/hyperv/compute/requests/set_vm_firmware.rb +15 -0
  78. data/lib/fog/hyperv/compute/requests/set_vm_floppy_disk_drive.rb +16 -0
  79. data/lib/fog/hyperv/compute/requests/set_vm_hard_disk_drive.rb +16 -0
  80. data/lib/fog/hyperv/compute/requests/set_vm_key_protector.rb +15 -0
  81. data/lib/fog/hyperv/compute/requests/set_vm_network_adapter.rb +25 -0
  82. data/lib/fog/hyperv/compute/requests/set_vm_network_adapter_vlan.rb +25 -0
  83. data/lib/fog/hyperv/compute/requests/set_vm_security.rb +17 -0
  84. data/lib/fog/hyperv/compute/requests/set_vm_switch.rb +9 -0
  85. data/lib/fog/hyperv/compute/requests/start_vm.rb +22 -0
  86. data/lib/fog/hyperv/compute/requests/stop_vm.rb +22 -0
  87. data/lib/fog/hyperv/compute/requests/suspend_vm.rb +22 -0
  88. data/lib/fog/hyperv/compute/requests/update_vm.rb +22 -0
  89. data/lib/fog/hyperv/compute.rb +206 -387
  90. data/lib/fog/hyperv/constants.rb +24 -0
  91. data/lib/fog/hyperv/fog_extensions/associations/collection.rb +11 -0
  92. data/lib/fog/hyperv/fog_extensions/attributes/datetime.rb +28 -0
  93. data/lib/fog/hyperv/fog_extensions/attributes/enum.rb +139 -0
  94. data/lib/fog/hyperv/fog_extensions/attributes/enumarray.rb +149 -0
  95. data/lib/fog/hyperv/fog_extensions/attributes/timespan.rb +27 -0
  96. data/lib/fog/hyperv/model.rb +142 -0
  97. data/lib/fog/hyperv/utils/powershell.rb +88 -0
  98. data/lib/fog/hyperv/utils/winrm.rb +233 -0
  99. data/lib/fog/hyperv/version.rb +4 -1
  100. data/lib/fog/hyperv.rb +51 -44
  101. metadata +187 -105
  102. data/.gitignore +0 -10
  103. data/.travis.yml +0 -11
  104. data/CHANGELOG.md +0 -52
  105. data/Gemfile +0 -4
  106. data/Rakefile +0 -10
  107. data/fog-hyperv.gemspec +0 -25
  108. data/lib/fog/collection.rb +0 -152
  109. data/lib/fog/hyperv/fog_extensions/enum.rb +0 -85
  110. data/lib/fog/hyperv/models/compute/bios.rb +0 -61
  111. data/lib/fog/hyperv/models/compute/cluster.rb +0 -64
  112. data/lib/fog/hyperv/models/compute/clusters.rb +0 -15
  113. data/lib/fog/hyperv/models/compute/com_port.rb +0 -22
  114. data/lib/fog/hyperv/models/compute/dvd_drive.rb +0 -92
  115. data/lib/fog/hyperv/models/compute/dvd_drives.rb +0 -12
  116. data/lib/fog/hyperv/models/compute/firmware.rb +0 -53
  117. data/lib/fog/hyperv/models/compute/floppy_drive.rb +0 -53
  118. data/lib/fog/hyperv/models/compute/floppy_drives.rb +0 -12
  119. data/lib/fog/hyperv/models/compute/hard_drive.rb +0 -110
  120. data/lib/fog/hyperv/models/compute/hard_drives.rb +0 -11
  121. data/lib/fog/hyperv/models/compute/host.rb +0 -45
  122. data/lib/fog/hyperv/models/compute/hosts.rb +0 -15
  123. data/lib/fog/hyperv/models/compute/network_adapter.rb +0 -145
  124. data/lib/fog/hyperv/models/compute/network_adapters.rb +0 -19
  125. data/lib/fog/hyperv/models/compute/server.rb +0 -220
  126. data/lib/fog/hyperv/models/compute/servers.rb +0 -21
  127. data/lib/fog/hyperv/models/compute/switch.rb +0 -65
  128. data/lib/fog/hyperv/models/compute/switches.rb +0 -15
  129. data/lib/fog/hyperv/models/compute/vhd.rb +0 -101
  130. data/lib/fog/hyperv/models/compute/vhds.rb +0 -16
  131. data/lib/fog/hyperv/requests/compute/add_vm_dvd_drive.rb +0 -12
  132. data/lib/fog/hyperv/requests/compute/add_vm_hard_disk_drive.rb +0 -12
  133. data/lib/fog/hyperv/requests/compute/add_vm_network_adapter.rb +0 -12
  134. data/lib/fog/hyperv/requests/compute/connect_vm_network_adapter.rb +0 -12
  135. data/lib/fog/hyperv/requests/compute/disconnect_vm_network_adapter.rb +0 -12
  136. data/lib/fog/hyperv/requests/compute/get_cluster.rb +0 -11
  137. data/lib/fog/hyperv/requests/compute/get_cluster_node.rb +0 -19
  138. data/lib/fog/hyperv/requests/compute/get_vhd.rb +0 -34
  139. data/lib/fog/hyperv/requests/compute/get_vm.rb +0 -20
  140. data/lib/fog/hyperv/requests/compute/get_vm_bios.rb +0 -21
  141. data/lib/fog/hyperv/requests/compute/get_vm_dvd_drive.rb +0 -20
  142. data/lib/fog/hyperv/requests/compute/get_vm_firmware.rb +0 -19
  143. data/lib/fog/hyperv/requests/compute/get_vm_floppy_disk_drive.rb +0 -20
  144. data/lib/fog/hyperv/requests/compute/get_vm_group.rb +0 -23
  145. data/lib/fog/hyperv/requests/compute/get_vm_hard_disk_drive.rb +0 -20
  146. data/lib/fog/hyperv/requests/compute/get_vm_host.rb +0 -12
  147. data/lib/fog/hyperv/requests/compute/get_vm_host_cluster.rb +0 -25
  148. data/lib/fog/hyperv/requests/compute/get_vm_network_adapter.rb +0 -27
  149. data/lib/fog/hyperv/requests/compute/get_vm_switch.rb +0 -27
  150. data/lib/fog/hyperv/requests/compute/mock_files/get_vm.json +0 -1
  151. data/lib/fog/hyperv/requests/compute/new_vhd.rb +0 -12
  152. data/lib/fog/hyperv/requests/compute/new_vm.rb +0 -15
  153. data/lib/fog/hyperv/requests/compute/new_vm_switch.rb +0 -13
  154. data/lib/fog/hyperv/requests/compute/remove_item.rb +0 -13
  155. data/lib/fog/hyperv/requests/compute/remove_vm.rb +0 -15
  156. data/lib/fog/hyperv/requests/compute/remove_vm_dvd_drive.rb +0 -12
  157. data/lib/fog/hyperv/requests/compute/remove_vm_hard_disk_drive.rb +0 -12
  158. data/lib/fog/hyperv/requests/compute/remove_vm_network_adapter.rb +0 -12
  159. data/lib/fog/hyperv/requests/compute/restart_vm.rb +0 -15
  160. data/lib/fog/hyperv/requests/compute/set_vm.rb +0 -12
  161. data/lib/fog/hyperv/requests/compute/set_vm_bios.rb +0 -13
  162. data/lib/fog/hyperv/requests/compute/set_vm_dvd_drive.rb +0 -12
  163. data/lib/fog/hyperv/requests/compute/set_vm_firmware.rb +0 -13
  164. data/lib/fog/hyperv/requests/compute/set_vm_hard_disk_drive.rb +0 -12
  165. data/lib/fog/hyperv/requests/compute/set_vm_network_adapter.rb +0 -12
  166. data/lib/fog/hyperv/requests/compute/set_vm_network_adapter_vlan.rb +0 -12
  167. data/lib/fog/hyperv/requests/compute/set_vm_switch.rb +0 -13
  168. data/lib/fog/hyperv/requests/compute/start_vm.rb +0 -15
  169. data/lib/fog/hyperv/requests/compute/stop_vm.rb +0 -15
  170. data/lib/fog/model.rb +0 -91
  171. data/test/fog/hyperv_test.rb +0 -7
  172. data/test/test_helper.rb +0 -4
  173. /data/lib/fog/hyperv/{requests/compute → compute/requests}/mock_files/get_cluster.json +0 -0
  174. /data/lib/fog/hyperv/{requests/compute → compute/requests}/mock_files/get_cluster_node.json +0 -0
  175. /data/lib/fog/hyperv/{requests/compute → compute/requests}/mock_files/get_vhd.json +0 -0
  176. /data/lib/fog/hyperv/{requests/compute → compute/requests}/mock_files/get_vm_bios.json +0 -0
  177. /data/lib/fog/hyperv/{requests/compute → compute/requests}/mock_files/get_vm_dvd_drive.json +0 -0
  178. /data/lib/fog/hyperv/{requests/compute → compute/requests}/mock_files/get_vm_firmware.json +0 -0
  179. /data/lib/fog/hyperv/{requests/compute → compute/requests}/mock_files/get_vm_floppy_disk_drive.json +0 -0
  180. /data/lib/fog/hyperv/{requests/compute → compute/requests}/mock_files/get_vm_hard_disk_drive.json +0 -0
  181. /data/lib/fog/hyperv/{requests/compute → compute/requests}/mock_files/get_vm_host.json +0 -0
  182. /data/lib/fog/hyperv/{requests/compute → compute/requests}/mock_files/get_vm_network_adapter.json +0 -0
  183. /data/lib/fog/hyperv/{requests/compute → compute/requests}/mock_files/get_vm_switch.json +0 -0
@@ -0,0 +1,362 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Fog::Hyperv::Compute
4
+ # rubocop:disable Metrics/ClassLength
5
+
6
+ class NetworkAdapter < Fog::Hyperv::Model
7
+ # rubocop:disable Layout/HashAlignment
8
+
9
+ # Network adapter statuses
10
+ # @note Defined by Microsoft.HyperV.PowerShell.VMNetworkAdapterOperationalStatus
11
+ NIC_STATUS_ENUM_VALUES = {
12
+ Unknown: 0,
13
+ Other: 1,
14
+ Ok: 2,
15
+ Degraded: 3,
16
+ Stressed: 4,
17
+ PredictiveFailure: 5,
18
+ Error: 6,
19
+ NonRecoverableError: 7,
20
+ Starting: 8,
21
+ Stopping: 9,
22
+ Stopped: 10,
23
+ InService: 11,
24
+ NoContact: 12,
25
+ LostCommunication: 13,
26
+ Aborted: 14,
27
+ Dormant: 15,
28
+ SupportingEntity: 16,
29
+ Completed: 17,
30
+ PowerMode: 18,
31
+ ProtocolVersion: 32_775
32
+ }.freeze
33
+ # rubocop:enable Layout/HashAlignment
34
+
35
+ NIC_FALLBACK_MAC = '000000000000'
36
+
37
+ # @!attribute [r] id
38
+ # @return [String] the GUID of this network adapter
39
+ identity :id
40
+
41
+ # @!attribute [r] computer_name
42
+ # @return [String] the name of the computer running the VM that this network adapter is attached to
43
+ attribute :computer_name
44
+ # @!attribute [r] vm_id
45
+ # @return [String,nil] the GUID of the VM this network adapter is attached to
46
+ attribute :vm_id
47
+ # @!attribute [r] is_management_os
48
+ # @return [Boolean] if the network adapter is attached to the management OS
49
+ attribute :is_management_os, type: :boolean
50
+
51
+ # attribute :acl_list
52
+ # @!attribute [r] connected
53
+ # @return [Boolean] if the network adapter is connected to the network
54
+ # @see connect
55
+ # @see disconnect
56
+ attribute :connected, type: :boolean
57
+
58
+ # @!attribute dynamic_mac_address_enabled
59
+ # @return [Boolean] if the network adapter is assigned a dynamic MAC address
60
+ attribute :dynamic_mac_address_enabled, type: :boolean, default: true
61
+ # @!attribute [r] ip_addresses
62
+ # @return [Array<String>] the IP addresses currently assigned to the network adapter
63
+ attribute :ip_addresses
64
+ # attribute :is_deleted
65
+ # @!attribute [r] is_external_adapter
66
+ # @return [Boolean] if the network adapter is external to the VM
67
+ attribute :is_external_adapter, type: :boolean
68
+ # @!attribute [r] is_legacy
69
+ # @return [Boolean] if the network adapter is using legacy option ROM
70
+ attribute :is_legacy, type: :boolean
71
+ # @!attribute mac_address
72
+ # @return [String] the MAC address of the network adapter
73
+ # @note Can only be changed if dynamic_mac_address_enabled is false
74
+ attribute :mac_address
75
+ # @!attribute name
76
+ # @return [String] the name of the network adapter
77
+ attribute :name
78
+ # @!attribute mac_address_spoofing
79
+ # @return [:On, :Off] if the NIC should be allowed to send packets with different MAC address
80
+ attribute :mac_address_spoofing, type: :hypervenum, values: Fog::Hyperv::ON_OFF_STATE_ENUM_VALUES
81
+ # @!attribute dhcp_guard
82
+ # @return [:On, :Off] if the NIC should drop DHCP messages from unauthorized VMs
83
+ attribute :dhcp_guard, type: :hypervenum, values: Fog::Hyperv::ON_OFF_STATE_ENUM_VALUES
84
+ # @!attribute router_guard
85
+ # @return [:On, :Off] if the NIC should drop RA/Redirection messages from unauthorized VMs
86
+ attribute :router_guard, type: :hypervenum, values: Fog::Hyperv::ON_OFF_STATE_ENUM_VALUES
87
+ # @!attribute allow_teaming
88
+ # @return [:On, :Off] if the NIC should be allowed to be teamed with other NICs on the same switch
89
+ attribute :allow_teaming, type: :hypervenum, values: Fog::Hyperv::ON_OFF_STATE_ENUM_VALUES
90
+ # @!attribute [r] status
91
+ # @return [Symbol] the status of the network adapter
92
+ # @see NIC_STATUS_ENUM_VALUES
93
+ attribute :status, type: :hypervenumarray, values: NIC_STATUS_ENUM_VALUES
94
+ # @!attribute switch_id
95
+ # @return [String] the ID of the switch the adapter is connected to
96
+ # @see connect
97
+ # @see disconnect
98
+ attribute :switch_id
99
+ # @!attribute switch_name
100
+ # @return [String] the name of the switch the adapter is connected to
101
+ # @see connect
102
+ # @see disconnect
103
+ attribute :switch_name
104
+
105
+ has_one :vlan_setting, :vlan_setting
106
+
107
+ # @!attribute [r] vlan_setting
108
+ # @return [NetworkAdapterVlan] the VLAN that the network adapter is connected to
109
+ def vlan_setting
110
+ return associations[:vlan_setting] if associations[:vlan_setting]
111
+
112
+ require_relative 'network_adapter_vlan'
113
+ attrs = { parent_adapter: self, service: @service, vm: @vm }
114
+
115
+ if persisted?
116
+ requires :id
117
+ requires :vm_id unless is_management_os
118
+
119
+ associations[:vlan_setting] = Fog::Hyperv::Compute::NetworkAdapterVlan.new(
120
+ **service.get_vm_network_adapter_vlan(
121
+ computer_name:,
122
+ management_os: is_management_os,
123
+ vm_id:,
124
+ id:,
125
+
126
+ _return_fields: Fog::Hyperv::Compute::NetworkAdapterVlan.attributes
127
+ ),
128
+ **attrs
129
+ )
130
+ else
131
+ associations[:vlan_setting] = Fog::Hyperv::Compute::NetworkAdapterVlan.new(attrs)
132
+ end
133
+ end
134
+
135
+ # Connect the network adapter to a given switch
136
+ # @param switch [Switch,String] a switch - or the ID/name of one - to connect to
137
+ def connect(switch, **options)
138
+ requires :id
139
+
140
+ if switch.is_a? Fog::Hyperv::Compute::Switch
141
+ new_switch_id = switch.id
142
+ new_switch_name = switch.name
143
+ else
144
+ new_switch_id = switch if switch.is_a?(String) && switch =~ Fog::Hyperv::GUID
145
+ new_switch_name = switch unless new_switch_id
146
+ end
147
+ options[:management_os] = true if is_management_os
148
+
149
+ service.connect_vm_network_adapter(
150
+ computer_name:,
151
+ vm_id:,
152
+ id:,
153
+
154
+ switch_id: new_switch_id,
155
+ switch_name: new_switch_name,
156
+
157
+ **options
158
+ )
159
+
160
+ old.switch_id = attributes[:switch_id] = new_switch_id
161
+ old.switch_name = attributes[:switch_name] = new_switch_name
162
+ true
163
+ end
164
+
165
+ # Disconnect the network adapter from any connected switch
166
+ def disconnect(**options)
167
+ requires :id
168
+
169
+ options[:management_os] = true if is_management_os
170
+ service.disconnect_vm_network_adapter(
171
+ computer_name:,
172
+ vm_id:,
173
+ id:,
174
+
175
+ **options
176
+ )
177
+
178
+ old.switch_id = attributes[:switch_id] = nil
179
+ old.switch_name = attributes[:switch_name] = nil
180
+ true
181
+ end
182
+
183
+ # @!attribute switch
184
+ # @return [Switch,nil] the switch the network adapter is connected to
185
+ # @see connect
186
+ # @see disconnect
187
+ def switch
188
+ service.switches.get(switch_id:, switch_name:, computer_name:) if switch_name.any? || switch_id.any?
189
+ end
190
+
191
+ def switch=(new_switch)
192
+ if new_switch.nil?
193
+ attributes[:switch_id] = nil
194
+ attributes[:switch_name] = nil
195
+
196
+ return
197
+ end
198
+
199
+ raise 'Not a switch' unless new_switch.is_a? Fog::Hyperv::Compute::Switch
200
+
201
+ attributes[:switch_id] = new_switch.id
202
+ attributes[:switch_name] = new_switch.name
203
+ end
204
+
205
+ def create
206
+ selector = {}
207
+ if is_management_os
208
+ selector[:management_os] = true
209
+ else
210
+ requires :vm_id
211
+
212
+ selector[:vm_id] = vm_id
213
+ end
214
+
215
+ args = { name:, switch_name: }
216
+ args[:is_legacy] = true if is_legacy
217
+ if !dynamic_mac_address_enabled && mac_address != NIC_FALLBACK_MAC
218
+ args[:static_mac_address] = mac_address
219
+ else
220
+ args[:dynamic_mac_address] = true
221
+ end
222
+ data = service.add_vm_network_adapter(
223
+ **selector,
224
+ computer_name:,
225
+
226
+ **args,
227
+
228
+ _return_fields: self.class.attributes
229
+ )
230
+ post_save_changes = {
231
+ mac_address_spoofing: mac_address_spoofing,
232
+ dhcp_guard: dhcp_guard,
233
+ router_guard: router_guard,
234
+ allow_teaming: allow_teaming
235
+ }.compact
236
+
237
+ merge_attributes(data)
238
+ vlan_setting.save if associations[:vlan_setting]
239
+ return self unless post_save_changes.any?
240
+
241
+ attributes.merge!(post_save_changes)
242
+ update if dirty?
243
+
244
+ self
245
+ end
246
+
247
+ def update
248
+ requires :id
249
+ requires :vm_id unless is_management_os
250
+
251
+ data = {}
252
+ if changed?(:name)
253
+ service.rename_vm_network_adapter(
254
+ computer_name: old.computer_name,
255
+ id: old.id,
256
+ vm_id: old.vm_id,
257
+ management_os: old.is_management_os,
258
+
259
+ new_name: name
260
+ )
261
+ data[:name] = name
262
+ end
263
+
264
+ changes = build_changelist
265
+ if changes.any?
266
+ data.merge!(
267
+ service.set_vm_network_adapter(
268
+ computer_name: old.computer_name,
269
+ id: old.id,
270
+ vm_id: old.vm_id,
271
+ management_os: old.is_management_os,
272
+
273
+ **changes,
274
+
275
+ _always_include: changes.keys,
276
+ _return_fields: self.class.attributes
277
+ )
278
+ )
279
+ end
280
+
281
+ if changed?(:switch_name) || changed?(:switch_id)
282
+ save_switch
283
+ data[:switch_name] = switch_name
284
+ data[:switch_id] = switch_id
285
+ end
286
+ vlan_setting.save if associations[:vlan_setting] && vlan_setting.dirty?
287
+
288
+ merge_attributes(data)
289
+ end
290
+
291
+ def destroy
292
+ requires :id
293
+ requires :vm_id unless is_management_os
294
+
295
+ service.remove_vm_network_adapter(
296
+ computer_name:,
297
+ vm_id:,
298
+ id:,
299
+ management_os: is_management_os
300
+ )
301
+ true
302
+ end
303
+
304
+ def reload
305
+ requires :id
306
+ requires :vm_id unless is_management_os
307
+
308
+ data = service.get_vm_network_adapter(
309
+ computer_name:,
310
+ vm_id:,
311
+ id:,
312
+ management_os: is_management_os,
313
+
314
+ _return_fields: self.class.attributes
315
+ )
316
+ return unless data
317
+
318
+ merge_attributes(data)
319
+ end
320
+
321
+ protected
322
+
323
+ def merge_attributes(new_attributes = {})
324
+ new_attributes[:ip_addresses] = [] if new_attributes[:ip_addresses] == ''
325
+ new_attributes[:mac_address] = NIC_FALLBACK_MAC if new_attributes[:mac_address].nil? || new_attributes[:mac_address] == ''
326
+
327
+ super
328
+ end
329
+
330
+ private
331
+
332
+ def build_changelist
333
+ changes = {
334
+ mac_address_spoofing: changed!(:mac_address_spoofing),
335
+ dhcp_guard: changed!(:dhcp_guard),
336
+ router_guard: changed!(:router_guard),
337
+ allow_teaming: changed!(:allow_teaming)
338
+ }.compact
339
+ unless is_management_os
340
+ if dynamic_mac_address_enabled
341
+ changes[:dynamic_mac_address] = changed!(:dynamic_mac_address_enabled)
342
+ elsif mac_address && mac_address != NIC_FALLBACK_MAC
343
+ changes[:static_mac_address] = changed!(:mac_address)
344
+ changes[:static_mac_address] ||= changed?(:dynamic_mac_address_enabled) ? mac_address : nil
345
+ end
346
+ end
347
+ changes.compact
348
+ end
349
+
350
+ def save_switch
351
+ selector = { computer_name:, vm_id:, id: }.compact
352
+ selector[:management_os] = true if is_management_os
353
+
354
+ if switch_name || switch_id
355
+ service.connect_vm_network_adapter(**selector, switch_name:, switch_id:)
356
+ else
357
+ service.disconnect_vm_network_adapter(**selector)
358
+ end
359
+ end
360
+ end
361
+ # rubocop:enable Metrics/ClassLength
362
+ end
@@ -0,0 +1,172 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Fog::Hyperv::Compute
4
+ class NetworkAdapterVlan < Fog::Hyperv::Model
5
+ # VLAN mode
6
+ # @note Defined by Microsoft.HyperV.PowerShell.VMNetworkAdapterVlanMode
7
+ VLAN_OPERATION_MODE = %i[
8
+ Untagged Access Trunk Private
9
+ ].freeze
10
+
11
+ # Extended mode for Private VLANs
12
+ # @note Defined by Microsoft.HyperV.PowerShell.VMNetworkAdapterPrivateVlanMode
13
+ PRIVATE_VLAN_MODE = %i[
14
+ Unknown Isolated Community Promiscuous
15
+ ].freeze
16
+
17
+ # @!attribute operation_mode
18
+ # @return [:Untagged, :Access, :Trunk, :Private] the active VLAN mode
19
+ attribute :operation_mode, type: :hypervenum, default: :Untagged, values: VLAN_OPERATION_MODE
20
+ # @!attribute private_vlan_mode
21
+ # @return [:Isolated, :Community, :Promiscuous] the type of private VLAN mode to use
22
+ attribute :private_vlan_mode, type: :hypervenum, default: :Isolated, values: PRIVATE_VLAN_MODE
23
+ # @!attribute access_vlan_id
24
+ # @return [Integer] the VLAN ID to use for operation_mode +:Access+
25
+ attribute :access_vlan_id, type: :integer
26
+ # @!attribute allowed_vlan_id_list
27
+ # @return [Array<Integer>] the list of allowed VLAN IDs to use for operation_mode +:Trunk+
28
+ attribute :allowed_vlan_id_list
29
+ # @!attribute native_vlan_id
30
+ # @return [Integer] the native VLAN ID to use for operation_mode +:Trunk+
31
+ attribute :native_vlan_id, type: :integer
32
+ # @!attribute primary_vlan_id
33
+ # @return [Integer] the primary VLAN ID to use for operation_mode +:Private+
34
+ attribute :primary_vlan_id, type: :integer
35
+ # @!attribute secondary_vlan_id
36
+ # @return [Integer] the secondary VLAN ID to use for private_vlan_mode +:Isolated+ or +:Community+
37
+ attribute :secondary_vlan_id, type: :integer
38
+ # @!attribute secondary_vlan_id_list
39
+ # @return [Array<Integer>] the list of secondary VLAN IDs to use for private_vlan_mode +:Promiscuous+
40
+ attribute :secondary_vlan_id_list
41
+
42
+ # @!attribute parent_adapter
43
+ # @return [NetworkAdapter] the network adapter this VLAN configuration applies to
44
+ has_one :parent_adapter, :network_adapters
45
+
46
+ alias identity :parent_adapter
47
+
48
+ def update
49
+ requires :parent_adapter
50
+
51
+ changes = build_changelist
52
+ return self unless changes.any?
53
+
54
+ merge_attributes(
55
+ service.set_vm_network_adapter_vlan(
56
+ computer_name: parent_adapter.computer_name,
57
+ vm_id: parent_adapter.vm_id,
58
+ id: parent_adapter.id,
59
+
60
+ **changes,
61
+
62
+ _always_include: changes.keys,
63
+ _return_fields: self.class.attributes
64
+ ) || {} # Unmodified object returns nothing
65
+ )
66
+ end
67
+
68
+ def reload
69
+ requires :parent_adapter
70
+
71
+ data = service.get_vm_network_adapter_vlan(
72
+ computer_name: parent_adapter.computer_name,
73
+ vm_id: parent_adapter.vm_id,
74
+ id: parent_adapter.id,
75
+
76
+ _return_fields: self.class.attributes
77
+ )
78
+ return unless data
79
+
80
+ merge_attributes(data)
81
+ end
82
+
83
+ def self.render_vlan_list(list)
84
+ ret = []
85
+ list = list.map(&:to_i).reject(&:zero?).sort.uniq
86
+
87
+ render_tuple = proc do |from, to|
88
+ next from if from == to
89
+
90
+ "#{from}-#{to}"
91
+ end
92
+
93
+ rangeend = rangestart = list.first
94
+ list.each do |vlan|
95
+ if vlan > rangeend + 1
96
+ ret << render_tuple.call(rangestart, rangeend)
97
+ rangestart = rangeend = vlan
98
+ else
99
+ rangeend = vlan
100
+ end
101
+ end
102
+ ret << render_tuple.call(rangestart, rangeend)
103
+
104
+ ret.join ','
105
+ end
106
+
107
+ private
108
+
109
+ def merge_attributes(new_attributes = {})
110
+ new_attributes[:allowed_vlan_id_list] = [] \
111
+ if new_attributes[:allowed_vlan_id_list].nil? || new_attributes[:allowed_vlan_id_list] == ''
112
+ new_attributes[:secondary_vlan_id_list] = [] \
113
+ if new_attributes[:secondary_vlan_id_list].nil? || new_attributes[:secondary_vlan_id_list] == ''
114
+
115
+ super
116
+ end
117
+
118
+ # VLAN changes require providing the full new configuration on any update, so build that list when necessary
119
+ def build_changelist
120
+ changes = {}
121
+ case operation_mode
122
+ when :Untagged
123
+ return changes unless changed?(:operation_mode)
124
+
125
+ changes[:untagged] = true
126
+ when :Access
127
+ requires :access_vlan_id
128
+ return changes unless changed?(:operation_mode, :access_vlan_id)
129
+
130
+ changes[:access] = true
131
+ changes[:access_vlan_id] = access_vlan_id
132
+ when :Trunk
133
+ requires :allowed_vlan_id_list, :native_vlan_id
134
+ return changes unless changed?(:operation_mode, :allowed_vlan_id_list, :native_vlan_id)
135
+
136
+ changes[:trunk] = true
137
+ changes[:allowed_vlan_id_list] = render_vlan_list(allowed_vlan_id_list)
138
+ changes[:native_vlan_id] = native_vlan_id
139
+ when :Private
140
+ requires :private_vlan_mode, :primary_vlan_id
141
+ case private_vlan_mode
142
+ when :Isolated
143
+ requires :secondary_vlan_id
144
+ return changes unless changed?(:operation_mode, :private_vlan_mode, :primary_vlan_id, :secondary_vlan_id)
145
+
146
+ changes[:isolated] = true
147
+ changes[:primary_vlan_id] = primary_vlan_id
148
+ changes[:secondary_vlan_id] = secondary_vlan_id
149
+ when :Community
150
+ requires :secondary_vlan_id
151
+ return changes unless changed?(:operation_mode, :private_vlan_mode, :primary_vlan_id, :secondary_vlan_id)
152
+
153
+ changes[:community] = true
154
+ changes[:primary_vlan_id] = primary_vlan_id
155
+ changes[:secondary_vlan_id] = secondary_vlan_id
156
+ when :Promiscuous
157
+ requires :secondary_vlan_id_list
158
+ return changes unless changed?(:operation_mode, :private_vlan_mode, :primary_vlan_id, :secondary_vlan_id_list)
159
+
160
+ changes[:promiscuous] = true
161
+ changes[:primary_vlan_id] = primary_vlan_id
162
+ changes[:secondary_vlan_id_list] = render_vlan_list(secondary_vlan_id_list)
163
+ end
164
+ end
165
+ changes
166
+ end
167
+
168
+ def render_vlan_list(list)
169
+ self.class.render_vlan_list list
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Fog::Hyperv::Compute
4
+ class NetworkAdapters < Fog::Hyperv::Collection
5
+ model Fog::Hyperv::Compute::NetworkAdapter
6
+
7
+ get_method :get_vm_network_adapter
8
+
9
+ attribute :computer_name
10
+ attribute :vm_id
11
+
12
+ def get(identifier, **filters)
13
+ id = identifier if identifier =~ /\Amicrosoft:#{Fog::Hyperv::GUID}\\#{Fog::Hyperv::GUID}\z/i
14
+ name = identifier unless id
15
+
16
+ id = nil if id&.empty?
17
+ name = nil if name&.empty?
18
+
19
+ raise ArgumentError, 'Must provide a name or combined GUID' if id.nil? && name.nil?
20
+
21
+ super(name:, _by_id: id, **filters)
22
+ end
23
+
24
+ protected
25
+
26
+ def search_attributes
27
+ super.merge(
28
+ _return_fields: model.attributes - %i[vlan_setting]
29
+ )
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Fog::Hyperv::Compute
4
+ # Security settings for a generation 2 (UEFI) VM
5
+ #
6
+ # @see https://learn.microsoft.com/en-us/windows/win32/hyperv_v2/msvm-securitysettingdata WMI definitions
7
+ class Security < Fog::Hyperv::Model
8
+ # @!attribute tpm_enabled
9
+ # @return [Boolean] if a vTPM is enabled for the VM
10
+ attribute :tpm_enabled, type: :boolean
11
+ # @!attribute [r] ksd_enabled
12
+ # @return [Boolean] if a key storage device is enabled for the VM
13
+ attribute :ksd_enabled, type: :boolean
14
+ # @!attribute [r] shielded
15
+ # @return [Boolean] if the VM is shielded
16
+ attribute :shielded, type: :boolean
17
+ # @!attribute encrypt_state_and_vm_migration_traffic
18
+ # @return [Boolean] if VM state and migration traffic should be encrypted
19
+ attribute :encrypt_state_and_vm_migration_traffic, type: :boolean
20
+ # @!attribute virtualization_based_security_opt_out
21
+ # @return [Boolean] if virtualization-based securty should be opted out of for the VM
22
+ attribute :virtualization_based_security_opt_out, type: :boolean
23
+ # @!attribute [r] bind_to_host_tpm
24
+ # @return [Boolean] if the VM is bound to the host TPM
25
+ attribute :bind_to_host_tpm, type: :boolean
26
+
27
+ # @!attribute [r] vm
28
+ # @return [Server] the VM this security configuration is attached to
29
+ has_one :vm, :servers
30
+
31
+ alias identity :hash
32
+
33
+ # @!attribute [r] key_protector
34
+ # @return [String, null] the key protector encryption key
35
+ # @see change_key_protector
36
+ def key_protector
37
+ requires :vm
38
+
39
+ @key_protector ||= service.get_vm_key_protector(
40
+ computer_name: vm.computer_name,
41
+ vm_id: vm.id
42
+ )[:value]
43
+ end
44
+
45
+ # Change the key protector for a VM
46
+ # @param protector [:new, :local, :last, String] the key protector to set.
47
+ # +:new+/+:local+ will generate a new host-local encryption key,
48
+ # +:last+ will restore the last successfully used encryption key
49
+ # @return [String] the binary key protector that was set
50
+ # @note a VM key protector can not be removed once set, only changed
51
+ def change_key_protector(protector)
52
+ requires :vm
53
+
54
+ protector = case protector
55
+ when :new, :local
56
+ { new_local_key_protector: true }
57
+ when :last
58
+ { restore_last_known_good_key_protector: true }
59
+ else
60
+ { key_protector: protector }
61
+ end
62
+
63
+ service.set_vm_key_protector(
64
+ computer_name: vm.computer_name,
65
+ vm_id: vm.id,
66
+
67
+ **protector
68
+ )
69
+ @key_protector = nil
70
+ true
71
+ end
72
+
73
+ def update
74
+ requires :vm
75
+
76
+ if tpm_enabled != old.tpm_enabled
77
+ meth = tpm_enabled ? :enable_vm_tpm : :disable_vm_tpm
78
+ service.public_send(meth, vm_id: vm.id)
79
+ end
80
+
81
+ changes = {
82
+ encrypt_state_and_vm_migration_traffic: changed!(:encrypt_state_and_vm_migration_traffic),
83
+ virtualization_based_security_opt_out: changed!(:virtualization_based_security_opt_out)
84
+ }.compact
85
+ return self unless changes.any?
86
+
87
+ merge_attributes(
88
+ service.set_vm_security(
89
+ computer_name: old.vm.computer_name,
90
+ vm_id: old.vm.id,
91
+
92
+ **changes,
93
+
94
+ _return_fields: self.class.attributes
95
+ )
96
+ )
97
+ end
98
+
99
+ def reload
100
+ requires :vm
101
+
102
+ data = service.get_vm_security(
103
+ computer_name: vm.computer_name,
104
+ vm_id: vm.id,
105
+
106
+ _return_fields: self.class.attributes
107
+ )
108
+ return unless data
109
+
110
+ merge_attributes(data)
111
+ end
112
+
113
+ private
114
+
115
+ def merge_attributes(attributes = {})
116
+ attributes[:vm] ||= @vm
117
+
118
+ super
119
+ end
120
+ end
121
+ end