vagrant-hypervnet 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 (32) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +16 -0
  3. data/README.md +54 -0
  4. data/Rakefile +8 -0
  5. data/Vagrantfile +104 -0
  6. data/lib/vagrant-hypervnet/action/disable_builtin_network_configure.rb +39 -0
  7. data/lib/vagrant-hypervnet/action/network.rb +328 -0
  8. data/lib/vagrant-hypervnet/action/ssh_server.rb +28 -0
  9. data/lib/vagrant-hypervnet/action.rb +31 -0
  10. data/lib/vagrant-hypervnet/cap/linux/nic_mac_addresses.rb +71 -0
  11. data/lib/vagrant-hypervnet/cap/linux/pre_configure_networks.rb +31 -0
  12. data/lib/vagrant-hypervnet/cap/vyos/post_configure_networks.rb +45 -0
  13. data/lib/vagrant-hypervnet/cap/windows/rsync.rb +60 -0
  14. data/lib/vagrant-hypervnet/cap/windows/sshd.rb +151 -0
  15. data/lib/vagrant-hypervnet/cap.rb +15 -0
  16. data/lib/vagrant-hypervnet/config.rb +36 -0
  17. data/lib/vagrant-hypervnet/driver.rb +197 -0
  18. data/lib/vagrant-hypervnet/errors.rb +34 -0
  19. data/lib/vagrant-hypervnet/scripts/add_vm_adapter.ps1 +15 -0
  20. data/lib/vagrant-hypervnet/scripts/connect_vm_adapter.ps1 +12 -0
  21. data/lib/vagrant-hypervnet/scripts/get_switch_by_address.ps1 +22 -0
  22. data/lib/vagrant-hypervnet/scripts/get_switch_by_name.ps1 +17 -0
  23. data/lib/vagrant-hypervnet/scripts/get_vm_adapters.ps1 +11 -0
  24. data/lib/vagrant-hypervnet/scripts/new_switch.ps1 +26 -0
  25. data/lib/vagrant-hypervnet/scripts/remove_vm_adapter.ps1 +9 -0
  26. data/lib/vagrant-hypervnet/scripts/utils/VagrantMessages/VagrantMessages.psm1 +27 -0
  27. data/lib/vagrant-hypervnet/version.rb +7 -0
  28. data/lib/vagrant-hypervnet.rb +89 -0
  29. data/locales/en.yml +69 -0
  30. data/sig/vagrant/hypervnet.rbs +6 -0
  31. data/vagrant-hypervnet.gemspec +26 -0
  32. metadata +73 -0
@@ -0,0 +1,31 @@
1
+ require "yaml"
2
+
3
+ module VagrantPlugins
4
+ module HyperVNet
5
+ module Cap
6
+ module Linux
7
+ class PreConfigureNetworks
8
+ extend Vagrant::Util::GuestInspection::Linux
9
+
10
+ def self.pre_configure_networks(machine)
11
+ if netplan?(machine.communicate)
12
+ yaml = ""
13
+ machine.communicate.sudo("netplan get 'ethernets'") do |type, data|
14
+ yaml << data if type == :stdout
15
+ end
16
+ ethernets = YAML.load(yaml)
17
+ ethernets_to_fix = ethernets.select {|k,v| (v["dhcp4"] || v["dhcp6"]) && !v["critical"]}
18
+ if !ethernets_to_fix.empty?
19
+ ethernets_to_fix.each do |k,v|
20
+ machine.communicate.sudo("netplan set 'ethernets.#{k}.critical=true'")
21
+ end
22
+ machine.communicate.sudo("netplan apply &")
23
+ machine.communicate.reset!
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,45 @@
1
+ require "yaml"
2
+
3
+ module VagrantPlugins
4
+ module HyperVNet
5
+ module Cap
6
+ module Vyos
7
+ class PostConfigureNetworks
8
+
9
+ @@logger = Log4r::Logger.new("vagrant::hypervnet::guest::vyos::post_configure_networks")
10
+
11
+ def self.post_configure_networks(machine)
12
+ nic_mac_addresses = machine.guest.capability(:nic_mac_addresses)
13
+ machine.communicate.tap do |comm|
14
+ commands = "#!/bin/vbash\n"
15
+ commands << "if [ \"$(id -g -n)\" != 'vyattacfg' ] ; then\n"
16
+ commands << " exec sg vyattacfg -c \"/bin/vbash $(readlink -f $0) $@\"\n"
17
+ commands << "fi\n"
18
+ commands << "source /opt/vyatta/etc/functions/script-template\n"
19
+ commands << "configure\n"
20
+
21
+ nic_mac_addresses.each do |nic|
22
+ commands << "set interfaces ethernet #{nic[:name]} hw-id '#{nic[:mac_address]}' \n"
23
+ end
24
+
25
+ commands << "commit\n"
26
+ commands << "save\n"
27
+ commands << "exit\n"
28
+
29
+ @@logger.debug("Commands: \n#{commands}")
30
+
31
+ temp = Tempfile.new("vagrant")
32
+ temp.binmode
33
+ temp.write(commands)
34
+ temp.close
35
+
36
+ comm.upload(temp.path, "/tmp/vagrant-configure-network")
37
+ comm.execute("bash /tmp/vagrant-configure-network")
38
+ comm.execute("rm -f /tmp/vagrant-configure-network")
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,60 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ module VagrantPlugins
5
+ module HyperVNet
6
+ module Cap
7
+ module Windows
8
+ class RSync
9
+
10
+ def self.rsync_installed(machine)
11
+ machine.communicate.test("rsync -V")
12
+ end
13
+
14
+ def self.rsync_install(machine)
15
+ if machine.config.hypervnet.install_rsync
16
+ machine.ui.detail(I18n.t("vagrant_hypervnet.rsync.install"))
17
+
18
+ msys2_base_url = "https://repo.msys2.org/distrib/x86_64/"
19
+ path_registry_key = "Registry::HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment"
20
+ msys2_url = Net::HTTP.get(URI.parse(msys2_base_url)).scan(/msys2-x86_64-\d+\.exe/)
21
+ .sort.map{|url| URI.join(msys2_base_url, url)}.last.to_s
22
+
23
+ cmds = []
24
+ cmds += [
25
+ "Invoke-WebRequest -Uri '#{msys2_url}' -OutFile C:\\msys2.exe",
26
+ "C:\\msys2.exe install --root 'C:\\MSYS2' --confirm-command",
27
+ "C:\\msys2\\usr\\bin\\pacman -S rsync --noconfirm",
28
+ "remove-item 'C:\\msys2.exe'"
29
+ ]
30
+ cmd = "$path = (Get-ItemProperty -Path '#{path_registry_key}' -Name path).path; "
31
+ cmd << "$path = \"$path;C:\\MSYS2\\usr\\bin\"; "
32
+ cmd << "Set-ItemProperty -Path '#{path_registry_key}' -Name path -Value $path"
33
+ cmds << cmd
34
+
35
+ machine.communicate.tap do |comm|
36
+ cmds.each do |cmd|
37
+ comm.execute(cmd, shell: :powershell)
38
+ end
39
+ end
40
+
41
+ if machine.guest.capability?(:sshd_reload)
42
+ machine.guest.capability(:sshd_reload)
43
+ end
44
+ end
45
+ end
46
+
47
+ def self.rsync_scrub_guestpath( machine, opts )
48
+ if opts[:guestpath] =~ /^([a-zA-Z]):/
49
+ opts[:guestpath].gsub( /^([a-zA-Z]):/, '/c/\1' )
50
+ elsif opts[:guestpath] !~ /^[\/\\][a-zA-Z][\/\\]/
51
+ "/c/#{opts[:guestpath]}"
52
+ else
53
+ opts[:guestpath]
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,151 @@
1
+
2
+ require 'vagrant/util/keypair'
3
+
4
+ module VagrantPlugins
5
+ module HyperVNet
6
+ module Cap
7
+ module Windows
8
+ class Sshd
9
+
10
+ def self.sshd_installed(machine)
11
+ machine.communicate.test("Get-Service -Name sshd")
12
+ end
13
+
14
+ def self.sshd_install(machine)
15
+ machine.ui.detail(I18n.t("vagrant_hypervnet.ssh.install"))
16
+
17
+ machine.communicate.sudo("Get-WindowsCapability -Online | ? Name -like 'OpenSSH.Server*' | Add-WindowsCapability -Online",
18
+ shell: :powershell, elevated: true)
19
+
20
+ if machine.config.ssh.insert_key
21
+ insert = false
22
+ ssh_info = machine.ssh_info
23
+ if !ssh_info.nil?
24
+ insert = ssh_info[:password] && ssh_info[:private_key_path].empty?
25
+ ssh_info[:private_key_path].each do |pk|
26
+ if insecure_key?(pk)
27
+ insert = true
28
+ machine.ui.detail("\n"+I18n.t("vagrant_hypervnet.ssh.inserting_insecure_detected"))
29
+ break
30
+ end
31
+ end
32
+ end
33
+
34
+ if insert
35
+ _pub, priv, openssh = Vagrant::Util::Keypair.create
36
+ machine.ui.detail("\n"+I18n.t("vagrant_hypervnet.ssh.inserting_random_key"))
37
+ insert_public_key(machine, openssh)
38
+
39
+ # Write out the private key in the data dir so that the
40
+ # machine automatically picks it up.
41
+ machine.data_dir.join("private_key").open("w+") do |f|
42
+ f.write(priv)
43
+ end
44
+
45
+ # Adjust private key file permissions if host provides capability
46
+ if machine.env.host.capability?(:set_ssh_key_permissions)
47
+ machine.env.host.capability(:set_ssh_key_permissions, machine.data_dir.join("private_key"))
48
+ end
49
+
50
+ # Remove the old key if it exists
51
+ machine.ui.detail(I18n.t("vagrant_hypervnet.ssh.inserting_remove_key"))
52
+ remove_public_key(machine, Vagrant.source_root.join("keys", "vagrant.pub").read.chomp)
53
+
54
+ machine.ui.detail(I18n.t("vagrant_hypervnet.ssh.inserted_key"))
55
+ end
56
+ end
57
+
58
+ cmds = []
59
+ cmds += [
60
+ 'Start-Service -Name sshd',
61
+ 'Set-Service -Name sshd -StartupType "Automatic"'
62
+ ]
63
+
64
+ machine.communicate.tap do |comm|
65
+ cmds.each do |cmd|
66
+ comm.execute(cmd, shell: :powershell)
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ def self.sshd_reload(machine)
73
+ machine.ui.detail(I18n.t("vagrant_hypervnet.ssh.reload"))
74
+ machine.communicate.execute('Restart-Service -Name sshd', shell: :powershell)
75
+ end
76
+
77
+ def self.insecure_key?(path)
78
+ return false if !path
79
+ return false if !File.file?(path)
80
+ source_path = Vagrant.source_root.join("keys", "vagrant")
81
+ return File.read(path).chomp == source_path.read.chomp
82
+ end
83
+
84
+ def self.insert_public_key(machine, contents)
85
+ contents = contents.strip
86
+ winssh_modify_authorized_keys machine do |keys|
87
+ if !keys.include?(contents)
88
+ keys << contents
89
+ end
90
+ end
91
+ end
92
+
93
+ def self.remove_public_key(machine, contents)
94
+ winssh_modify_authorized_keys machine do |keys|
95
+ keys.delete(contents)
96
+ end
97
+ end
98
+
99
+ def self.winssh_modify_authorized_keys(machine)
100
+ comm = machine.communicate
101
+ directories = fetch_guest_paths(comm)
102
+ data_dir = directories[:data]
103
+ temp_dir = directories[:temp]
104
+
105
+ remote_ssh_dir = "#{data_dir}\\ssh"
106
+ comm.execute("New-Item -Path '#{remote_ssh_dir}' -ItemType directory -Force", shell: "powershell")
107
+ remote_upload_path = "#{temp_dir}\\vagrant-insert-pubkey-#{Time.now.to_i}"
108
+ remote_authkeys_path = "#{remote_ssh_dir}\\administrators_authorized_keys"
109
+
110
+ keys_file = Tempfile.new("vagrant-windows-insert-public-key")
111
+ keys_file.close
112
+ # Check if an authorized_keys file already exists
113
+ result = comm.execute("dir \"#{remote_authkeys_path}\"", shell: "cmd", error_check: false)
114
+ if result == 0
115
+ comm.download(remote_authkeys_path, keys_file.path)
116
+ keys = File.read(keys_file.path).split(/[\r\n]+/)
117
+ else
118
+ keys = []
119
+ end
120
+ yield keys
121
+ File.write(keys_file.path, keys.join("\r\n") + "\r\n")
122
+ comm.upload(keys_file.path, remote_upload_path)
123
+ keys_file.delete
124
+ comm.execute(<<-EOC.gsub(/^\s*/, ""), shell: "powershell")
125
+ Set-Acl "#{remote_upload_path}" (Get-Acl "#{remote_authkeys_path}")
126
+ Move-Item -Force "#{remote_upload_path}" "#{remote_authkeys_path}"
127
+ EOC
128
+ end
129
+
130
+ # Fetch user's temporary and data directory paths from the Windows guest
131
+ #
132
+ # @param [Communicator]
133
+ # @return [Hash] {:temp, :data}
134
+ def self.fetch_guest_paths(communicator)
135
+ output = ""
136
+ communicator.execute("Write-Output $env:TEMP\nWrite-Output $env:ProgramData", shell: "powershell") do |type, data|
137
+ if type == :stdout
138
+ output << data
139
+ end
140
+ end
141
+ temp_dir, data_dir = output.strip.split(/[\r\n]+/)
142
+ if temp_dir.nil? || data_dir.nil?
143
+ raise Errors::PublicKeyDirectoryFailure
144
+ end
145
+ {temp: temp_dir, data: data_dir}
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'driver'
2
+
3
+ module VagrantPlugins
4
+ module HyperVNet
5
+ module Cap
6
+ # Reads the network interface card MAC addresses and returns them.
7
+ #
8
+ # @return [Hash<String, String>] Adapter => MAC address
9
+ def self.nic_mac_addresses(machine)
10
+ driver = Driver.new(machine.id)
11
+ driver.read_vm_mac_addresses
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,36 @@
1
+ require "vagrant"
2
+
3
+ module VagrantPlugins
4
+ module HyperVNet
5
+ class Config < Vagrant.plugin("2", :config)
6
+
7
+ attr_reader :network_adapters
8
+
9
+ attr_accessor :install_ssh_server
10
+ attr_accessor :install_rsync
11
+
12
+ def initialize
13
+ @network_adapters = []
14
+ @install_ssh_server = UNSET_VALUE
15
+ @install_rsync = UNSET_VALUE
16
+
17
+ network_adapter(:nat)
18
+ end
19
+
20
+ def network_adapter(type, **opts)
21
+ @network_adapters << [type, opts]
22
+ end
23
+
24
+ def finalize!
25
+ @install_ssh_server = true if @install_ssh_server == UNSET_VALUE
26
+ @install_rsync = true if @install_rsync == UNSET_VALUE
27
+ end
28
+
29
+ def validate(machine)
30
+ errors = _detected_errors
31
+
32
+ {"Hyper-V network" => errors}
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,197 @@
1
+ require "json"
2
+ require "vagrant/util/powershell"
3
+
4
+ require_relative "errors"
5
+
6
+ module VagrantPlugins
7
+ module HyperVNet
8
+ class Driver
9
+ ERROR_REGEXP = /===Begin-Error===(.+?)===End-Error===/m
10
+ OUTPUT_REGEXP = /===Begin-Output===(.+?)===End-Output===/m
11
+
12
+ # @return [String] VM Id
13
+ attr_reader :vmId
14
+
15
+ def initialize(id)
16
+ @vmId = id
17
+ @logger = Log4r::Logger.new("vagrant::hypervnet::driver")
18
+ end
19
+
20
+ # Execute a PowerShell command and process the results
21
+ #
22
+ # @param [String] path Path to PowerShell script
23
+ # @param [Hash] options Options to pass to command
24
+ #
25
+ # @return [Object, nil] If the command returned JSON content
26
+ # it will be parsed and returned, otherwise
27
+ # nil will be returned
28
+ def execute(path, options={})
29
+ if path.is_a?(Symbol)
30
+ path = "#{path}.ps1"
31
+ end
32
+ r = execute_powershell(path, options)
33
+
34
+ # We only want unix-style line endings within Vagrant
35
+ r.stdout.gsub!("\r\n", "\n")
36
+ r.stderr.gsub!("\r\n", "\n")
37
+
38
+ error_match = ERROR_REGEXP.match(r.stdout)
39
+ output_match = OUTPUT_REGEXP.match(r.stdout)
40
+
41
+ if error_match
42
+ data = JSON.parse(error_match[1])
43
+
44
+ @logger.info("Error in #{path}: #{data["error"]}")
45
+ # We have some error data.
46
+ raise Errors::PowerShellError,
47
+ script: path,
48
+ stderr: data["error"]
49
+ end
50
+
51
+ if r.exit_code != 0
52
+ @logger.info("Error in #{path}: #{r.stderr}")
53
+ raise Errors::PowerShellError,
54
+ script: path,
55
+ stderr: r.stderr
56
+ end
57
+
58
+ # Nothing
59
+ return nil if !output_match
60
+ return JSON.parse(output_match[1])
61
+ end
62
+
63
+ def find_switch_by_name(name)
64
+ data = execute(:get_switch_by_name, Name: name)
65
+ if data && data.kind_of?(Array)
66
+ data = data[0]
67
+ end
68
+
69
+ if data
70
+ switch = {}
71
+ switch[:name] = data["Name"]
72
+ switch[:type] = data["SwitchType"]
73
+ end
74
+
75
+ switch
76
+ end
77
+
78
+ def find_switch_by_address(ip_address, prefix_length)
79
+ data = execute(:get_switch_by_address, DestinationPrefix: "#{ip_address}/#{prefix_length}")
80
+ if data && data.kind_of?(Array)
81
+ data = data[0]
82
+ end
83
+
84
+ if data
85
+ switch = {}
86
+ switch[:name] = data["Name"]
87
+ switch[:type] = data["SwitchType"]
88
+ end
89
+
90
+ switch
91
+ end
92
+
93
+ def read_vm_mac_addresses
94
+ adapters = {}
95
+
96
+ data = execute(:get_vm_adapters, VmId: @vmId)
97
+ if data
98
+ if data.kind_of?(Hash)
99
+ data = [] << data
100
+ end
101
+
102
+ data.each.with_index(1) do |value, index|
103
+ adapters[index] = value["MacAddress"]
104
+ end
105
+ end
106
+
107
+ adapters
108
+ end
109
+
110
+ def read_vm_network_adapters
111
+ adapters = []
112
+
113
+ data = execute(:get_vm_adapters, VmId: @vmId)
114
+ if data
115
+ if data.kind_of?(Hash)
116
+ data = [] << data
117
+ end
118
+ data.each do |value|
119
+ adapter = {}
120
+ adapter[:id] = value["Id"]
121
+ adapter[:name] = value["Name"]
122
+ adapter[:switch] = value["SwitchName"]
123
+ adapter[:mac_address] = value["MacAddress"]
124
+ adapters << adapter
125
+ end
126
+ end
127
+ adapters
128
+ end
129
+
130
+ def create_switch(type, name, ip_address = nil, prefix_length = nil)
131
+ case type
132
+ when :internal
133
+ data = execute(:new_switch, Name: name, SwitchType: "Internal", IPAddress: ip_address, PrefixLength: prefix_length)
134
+ when :private
135
+ data = execute(:new_switch, Name: name, SwitchType: "Private")
136
+ end
137
+
138
+ if data
139
+ switch = {}
140
+ switch[:name] = data["Name"]
141
+ switch[:type] = data["SwitchType"]
142
+ end
143
+
144
+ switch
145
+ end
146
+
147
+ def add_vm_adapter(switch)
148
+ data = execute(:add_vm_adapter, VmId: @vmId, SwitchName: switch)
149
+
150
+ adapter = {}
151
+ adapter[:id] = data["Id"]
152
+ adapter[:name] = data["Name"]
153
+ adapter[:switch] = data["SwitchName"]
154
+ adapter[:mac_address] = data["MacAddress"]
155
+
156
+ adapter
157
+ end
158
+
159
+ def remove_vm_adapter(id)
160
+ execute(:remove_vm_adapter, VmId: @vmId, Id: id)
161
+ end
162
+
163
+ def connect_vm_adapter(id, switch)
164
+ execute(:connect_vm_adapter, VmId: @vmId, Id: id, SwitchName: switch)
165
+ end
166
+
167
+ protected
168
+
169
+ def execute_powershell(path, options, &block)
170
+ lib_path = Pathname.new(File.expand_path("../scripts", __FILE__))
171
+ mod_path = Vagrant::Util::Platform.wsl_to_windows_path(lib_path.join("utils")).to_s.gsub("/", "\\")
172
+ path = Vagrant::Util::Platform.wsl_to_windows_path(lib_path.join(path)).to_s.gsub("/", "\\")
173
+ options = options || {}
174
+ ps_options = []
175
+ options.each do |key, value|
176
+ next if !value || value.to_s.empty?
177
+ next if value == false
178
+ ps_options << "-#{key}"
179
+ # If the value is a TrueClass assume switch
180
+ next if value == true
181
+ ps_options << "'#{value}'"
182
+ end
183
+
184
+ # Always have a stop error action for failures
185
+ ps_options << "-ErrorAction" << "Stop"
186
+
187
+ # Include our module path so we can nicely load helper modules
188
+ opts = {
189
+ notify: [:stdout, :stderr, :stdin],
190
+ module_path: mod_path
191
+ }
192
+
193
+ Vagrant::Util::PowerShell.execute(path, *ps_options, **opts, &block)
194
+ end
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,34 @@
1
+ module VagrantPlugins
2
+ module HyperVNet
3
+ module Errors
4
+ # A convenient superclass for all our errors.
5
+ class HyperVNetError < Vagrant::Errors::VagrantError
6
+ error_namespace("vagrant_hypervnet.errors")
7
+ end
8
+
9
+ class BridgeUndefinedInPublicNetwork < HyperVNetError
10
+ error_key(:bridge_undefined_in_public_network)
11
+ end
12
+
13
+ class IpUndefinedInPrivateNetwork < HyperVNetError
14
+ error_key(:ip_undefined_in_private_network)
15
+ end
16
+
17
+ class PowerShellError < HyperVNetError
18
+ error_key(:powershell_error)
19
+ end
20
+
21
+ class NetworkAddressInvalid < HyperVNetError
22
+ error_key(:network_address_invalid)
23
+ end
24
+
25
+ class NetworkNotFound < HyperVNetError
26
+ error_key(:network_not_found)
27
+ end
28
+
29
+ class NetworkTypeNotSupported < HyperVNetError
30
+ error_key(:network_type_not_supported)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,15 @@
1
+ #Requires -Modules VagrantMessages
2
+
3
+ param (
4
+ [parameter (Mandatory=$true)]
5
+ [string]$VmId,
6
+ [parameter (Mandatory=$true)]
7
+ [string]$SwitchName
8
+
9
+ )
10
+
11
+ $vm = Get-VM -Id $VmId
12
+ $adapter = Add-VMNetworkAdapter -PassThru -VM $vm -SwitchName $SwitchName |
13
+ Select-Object -Property "Name", "Id", "SwitchName", "MacAddress"
14
+
15
+ Write-OutputMessage $(ConvertTo-JSON $adapter)
@@ -0,0 +1,12 @@
1
+ param (
2
+ [parameter (Mandatory=$true)]
3
+ [string]$VmId,
4
+ [parameter (Mandatory=$true)]
5
+ [string]$Id,
6
+ [parameter (Mandatory=$true)]
7
+ [string]$SwitchName
8
+
9
+ )
10
+
11
+ $vm = Get-VM -Id $VmId
12
+ Get-VMNetworkAdapter -VM $vm | Where-Object -Property Id -EQ -Value $Id | Connect-VMNetworkAdapter -SwitchName $SwitchName
@@ -0,0 +1,22 @@
1
+ #Requires -Modules VagrantMessages
2
+
3
+ param (
4
+ [parameter (Mandatory=$true)]
5
+ [string]$DestinationPrefix
6
+ )
7
+
8
+ $switches = @()
9
+
10
+ foreach($route in Get-NetRoute | Where-Object -Property DestinationPrefix -EQ -Value $DestinationPrefix) {
11
+ foreach($adapter in Get-NetAdapter -InterfaceIndex $route.ifIndex) {
12
+ foreach($vmAdapter in Get-VMNetworkAdapter -ManagementOS | Where-Object -Property DeviceId -EQ -Value $adapter.DeviceId) {
13
+ foreach($switch in Get-VMSwitch -Name $vmAdapter.SwitchName |
14
+ Select-Object -Property Name,
15
+ @{Name='SwitchType';Expression={"$($_.SwitchType)"}},
16
+ @{Name='NetAdapter';Expression={$switch_adapter[$_.Name]}}) {
17
+ $switches += $switch
18
+ }
19
+ }
20
+ }
21
+ }
22
+ Write-OutputMessage $(ConvertTo-JSON $switches)
@@ -0,0 +1,17 @@
1
+ #Requires -Modules VagrantMessages
2
+
3
+ param (
4
+ [parameter (Mandatory=$true)]
5
+ [string]$Name
6
+ )
7
+
8
+ $switches = @()
9
+
10
+ foreach($switch in Get-VMSwitch | Where-Object -Property Name -EQ -Value $Name |
11
+ Select-Object -Property Name,
12
+ @{Name='SwitchType';Expression={"$($_.SwitchType)"}},
13
+ @{Name='NetAdapter';Expression={$switch_adapter[$_.Name]}}) {
14
+ $switches += $switch
15
+ }
16
+
17
+ Write-OutputMessage $(ConvertTo-JSON $switches)
@@ -0,0 +1,11 @@
1
+ #Requires -Modules VagrantMessages
2
+
3
+ param (
4
+ [parameter (Mandatory=$true)]
5
+ [string]$VmId
6
+ )
7
+ $vm = Get-VM -Id $VmId
8
+ $adapters = Get-VMNetworkAdapter -VM $vm |
9
+ Select-Object -Property "Name", "Id", "SwitchName", "MacAddress"
10
+
11
+ Write-OutputMessage $(ConvertTo-JSON $adapters)
@@ -0,0 +1,26 @@
1
+ #Requires -Modules VagrantMessages
2
+
3
+ param (
4
+ [parameter (Mandatory=$true)]
5
+ [string]$Name,
6
+ [parameter (Mandatory=$true)]
7
+ [string]$SwitchType,
8
+ [parameter (Mandatory=$false)]
9
+ [string]$IPAddress,
10
+ [parameter (Mandatory=$false)]
11
+ [string]$PrefixLength
12
+
13
+ )
14
+
15
+ $switch = New-VMSwitch -Name $Name -SwitchType $SwitchType
16
+
17
+ if($IPAddress) {
18
+ $vmAdapter = Get-VMNetworkAdapter -ManagementOS -SwitchName $switch.Name
19
+ $adapter = Get-NetAdapter | Where-Object -Property DeviceId -EQ -Value $vmAdapter.DeviceId
20
+ New-NetIPAddress -IPAddress $IPAddress -PrefixLength $PrefixLength -InterfaceIndex $adapter.ifIndex
21
+ }
22
+
23
+ Write-OutputMessage $($switch | Select-Object -Property Name,
24
+ @{Name='SwitchType';Expression={"$($_.SwitchType)"}},
25
+ @{Name='NetAdapter';Expression={$switch_adapter[$_.Name]}} |
26
+ ConvertTo-JSON)