fog-hyperv 0.0.9 → 0.1.1

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 +50 -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 +183 -0
  16. data/lib/fog/hyperv/compute/models/hard_drives.rb +28 -0
  17. data/lib/fog/hyperv/compute/models/host.rb +63 -0
  18. data/lib/fog/hyperv/compute/models/hosts.rb +13 -0
  19. data/lib/fog/hyperv/compute/models/network_adapter.rb +368 -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 +16 -0
  69. data/lib/fog/hyperv/compute/requests/resize_vhd.rb +16 -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 +53 -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,368 @@
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: computer_name,
122
+ management_os: is_management_os,
123
+ vm_id: vm_id,
124
+ id: 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: computer_name,
151
+ vm_id: vm_id,
152
+ id: 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: computer_name,
172
+ vm_id: vm_id,
173
+ id: 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
+ return unless switch_name.any? || switch_id.any?
189
+
190
+ service.switches.get(
191
+ switch_id: switch_id,
192
+ switch_name: switch_name,
193
+ computer_name: computer_name
194
+ )
195
+ end
196
+
197
+ def switch=(new_switch)
198
+ if new_switch.nil?
199
+ attributes[:switch_id] = nil
200
+ attributes[:switch_name] = nil
201
+
202
+ return
203
+ end
204
+
205
+ raise 'Not a switch' unless new_switch.is_a? Fog::Hyperv::Compute::Switch
206
+
207
+ attributes[:switch_id] = new_switch.id
208
+ attributes[:switch_name] = new_switch.name
209
+ end
210
+
211
+ def create
212
+ selector = {}
213
+ if is_management_os
214
+ selector[:management_os] = true
215
+ else
216
+ requires :vm_id
217
+
218
+ selector[:vm_id] = vm_id
219
+ end
220
+
221
+ args = attributes.slice(:name, :switch_name)
222
+ args[:is_legacy] = true if is_legacy
223
+ if !dynamic_mac_address_enabled && mac_address != NIC_FALLBACK_MAC
224
+ args[:static_mac_address] = mac_address
225
+ else
226
+ args[:dynamic_mac_address] = true
227
+ end
228
+ data = service.add_vm_network_adapter(
229
+ **selector,
230
+ computer_name: computer_name,
231
+
232
+ **args,
233
+
234
+ _return_fields: self.class.attributes
235
+ )
236
+ post_save_changes = {
237
+ mac_address_spoofing: mac_address_spoofing,
238
+ dhcp_guard: dhcp_guard,
239
+ router_guard: router_guard,
240
+ allow_teaming: allow_teaming
241
+ }.compact
242
+
243
+ merge_attributes(data)
244
+ vlan_setting.save if associations[:vlan_setting]
245
+ return self unless post_save_changes.any?
246
+
247
+ attributes.merge!(post_save_changes)
248
+ update if dirty?
249
+
250
+ self
251
+ end
252
+
253
+ def update
254
+ requires :id
255
+ requires :vm_id unless is_management_os
256
+
257
+ data = {}
258
+ if changed?(:name)
259
+ service.rename_vm_network_adapter(
260
+ computer_name: old.computer_name,
261
+ id: old.id,
262
+ vm_id: old.vm_id,
263
+ management_os: old.is_management_os,
264
+
265
+ new_name: name
266
+ )
267
+ data[:name] = name
268
+ end
269
+
270
+ changes = build_changelist
271
+ if changes.any?
272
+ data.merge!(
273
+ service.set_vm_network_adapter(
274
+ computer_name: old.computer_name,
275
+ id: old.id,
276
+ vm_id: old.vm_id,
277
+ management_os: old.is_management_os,
278
+
279
+ **changes,
280
+
281
+ _always_include: changes.keys,
282
+ _return_fields: self.class.attributes
283
+ )
284
+ )
285
+ end
286
+
287
+ if changed?(:switch_name) || changed?(:switch_id)
288
+ save_switch
289
+ data[:switch_name] = switch_name
290
+ data[:switch_id] = switch_id
291
+ end
292
+ vlan_setting.save if associations[:vlan_setting] && vlan_setting.dirty?
293
+
294
+ merge_attributes(data)
295
+ end
296
+
297
+ def destroy
298
+ requires :id
299
+ requires :vm_id unless is_management_os
300
+
301
+ service.remove_vm_network_adapter(
302
+ computer_name: computer_name,
303
+ vm_id: vm_id,
304
+ id: id,
305
+ management_os: is_management_os
306
+ )
307
+ true
308
+ end
309
+
310
+ def reload
311
+ requires :id
312
+ requires :vm_id unless is_management_os
313
+
314
+ data = service.get_vm_network_adapter(
315
+ computer_name: computer_name,
316
+ vm_id: vm_id,
317
+ id: id,
318
+ management_os: is_management_os,
319
+
320
+ _return_fields: self.class.attributes
321
+ )
322
+ return unless data
323
+
324
+ merge_attributes(data)
325
+ end
326
+
327
+ protected
328
+
329
+ def merge_attributes(new_attributes = {})
330
+ new_attributes[:ip_addresses] = [] if new_attributes[:ip_addresses] == ''
331
+ new_attributes[:mac_address] = NIC_FALLBACK_MAC if new_attributes[:mac_address].nil? || new_attributes[:mac_address] == ''
332
+
333
+ super
334
+ end
335
+
336
+ private
337
+
338
+ def build_changelist
339
+ changes = {
340
+ mac_address_spoofing: changed!(:mac_address_spoofing),
341
+ dhcp_guard: changed!(:dhcp_guard),
342
+ router_guard: changed!(:router_guard),
343
+ allow_teaming: changed!(:allow_teaming)
344
+ }.compact
345
+ unless is_management_os
346
+ if dynamic_mac_address_enabled
347
+ changes[:dynamic_mac_address] = changed!(:dynamic_mac_address_enabled)
348
+ elsif mac_address && mac_address != NIC_FALLBACK_MAC
349
+ changes[:static_mac_address] = changed!(:mac_address)
350
+ changes[:static_mac_address] ||= changed?(:dynamic_mac_address_enabled) ? mac_address : nil
351
+ end
352
+ end
353
+ changes.compact
354
+ end
355
+
356
+ def save_switch
357
+ selector = attributes.slice(:computer_name, :vm_id, :id).compact
358
+ selector[:management_os] = true if is_management_os
359
+
360
+ if switch_name || switch_id
361
+ service.connect_vm_network_adapter(**selector, switch_name: switch_name, switch_id: switch_id)
362
+ else
363
+ service.disconnect_vm_network_adapter(**selector)
364
+ end
365
+ end
366
+ end
367
+ # rubocop:enable Metrics/ClassLength
368
+ 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: 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