Class: VagrantPlugins::WindowsDomain::Provisioner
- Inherits:
-
Object
- Object
- VagrantPlugins::WindowsDomain::Provisioner
- Defined in:
- lib/vagrant-windows-domain/provisioner.rb
Overview
Windows Domain Provisioner Plugin.
Connects and Removes a guest Machine from a Windows Domain.
Constant Summary collapse
- WINDOWS_DOMAIN_GUEST_RUNNER_PATH =
Default path for storing the transient script runner
"c:/tmp/vagrant-windows-domain-runner.ps1"
Instance Attribute Summary collapse
-
#old_computer_name ⇒ Object
The current Computer Name.
-
#restart_sleep_duration ⇒ Object
Returns the value of attribute restart_sleep_duration.
Instance Method Summary collapse
-
#configure(root_config) ⇒ Object
Configures the Provisioner.
-
#destroy ⇒ Object
Cleanup after a destroy action.
-
#generate_command_arguments(add_to_domain = true) ⇒ Object
Generates the argument list.
-
#generate_command_runner_script(add_to_domain = true) ⇒ String
Generates a PowerShell runner script from an ERB template.
-
#get_guest_computer_name(machine) ⇒ Object
Gets the Computer Name from the guest machine.
-
#initialize(machine, config) ⇒ Provisioner
constructor
Constructs the Provisioner Plugin.
-
#join_domain ⇒ Object
Join the guest machine to a Windows Domain.
-
#leave_domain ⇒ Object
(also: #unjoin_domain)
Removes the guest machine from a Windows Domain.
-
#provision ⇒ Object
Run the Provisioner!.
-
#remove_command_runner_script ⇒ Object
Remove temporary run script as it may contain sensitive plain-text credentials.
-
#restart_guest ⇒ Object
Restarts the Computer and waits.
-
#run_remote_command_runner(script_path) ⇒ boolean
Runs the PowerShell script on the guest machine.
-
#set_credentials ⇒ Object
Ensure credentials are provided.
-
#verify_binary(binary) ⇒ Object
Verify a binarycommand is executable on the guest machine.
-
#verify_guest_capability ⇒ Object
Verify that we can call the remote operations.
-
#windows? ⇒ Boolean
Is the guest Windows?.
-
#write_command_runner_script(script) ⇒ String
Writes the PowerShell runner script to a location on the guest.
Constructor Details
#initialize(machine, config) ⇒ Provisioner
Constructs the Provisioner Plugin.
36 37 38 39 40 41 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 36 def initialize(machine, config) super @logger = Log4r::Logger.new("vagrant::provisioners::vagrant_windows_domain") @restart_sleep_duration = 10 end |
Instance Attribute Details
#old_computer_name ⇒ Object
The current Computer Name.
Used to determine whether or not we need to rename the computer on join. This parameter should not be manually set.
29 30 31 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 29 def old_computer_name @old_computer_name end |
#restart_sleep_duration ⇒ Object
Returns the value of attribute restart_sleep_duration.
23 24 25 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 23 def restart_sleep_duration @restart_sleep_duration end |
Instance Method Details
#configure(root_config) ⇒ Object
Configures the Provisioner.
46 47 48 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 46 def configure(root_config) raise WindowsDomainError, :unsupported_platform if !windows? end |
#destroy ⇒ Object
Cleanup after a destroy action.
This is the method called when destroying a machine that allows for any state related to the machine created by the provisioner to be cleaned up.
105 106 107 108 109 110 111 112 113 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 105 def destroy if @config && @config.include?("domain") set_credentials leave_domain else @logger.debug("Not leaving domain on `destroy` action - no valid configuration detected") return end end |
#generate_command_arguments(add_to_domain = true) ⇒ Object
Generates the argument list
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 162 def generate_command_arguments(add_to_domain=true) if add_to_domain params = {"-DomainName" => @config.domain } if @config.unsecure params["-Unsecure"] = nil else params["-Credential $credentials"] = nil end if @config.computer_name != nil && @config.computer_name != @old_computer_name params["-NewName"] = "'#{@config.computer_name}'" end if @config.ou_path params["-OUPath"] = "'#{@config.ou_path}'" end else params = {} if !@config.unsecure params["-UnjoinDomainCredential $credentials"] = nil end end # Remove with unsecure join_params = @config..map { |a| "#{a}" }.join(',') params.map { |k,v| "#{k}" + (!v.nil? ? " #{v}": '') }.join(' ') + join_params end |
#generate_command_runner_script(add_to_domain = true) ⇒ String
Generates a PowerShell runner script from an ERB template
147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 147 def generate_command_runner_script(add_to_domain=true) path = File.("../templates/runner.ps1", __FILE__) Vagrant::Util::TemplateRenderer.render(path, options: { config: @config, username: @config.username, password: @config.password, domain: @config.domain, add_to_domain: add_to_domain, unsecure: @config.unsecure, parameters: generate_command_arguments(add_to_domain) }) end |
#get_guest_computer_name(machine) ⇒ Object
Gets the Computer Name from the guest machine
246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 246 def get_guest_computer_name(machine) computerName = "" machine.communicate.shell.powershell("$env:COMPUTERNAME") do |type, data| if !data.chomp.empty? if [:stderr, :stdout].include?(type) computerName = data.chomp @logger.info("Detected guest computer name: #{computerName}") end end end computerName end |
#join_domain ⇒ Object
Join the guest machine to a Windows Domain.
Generates, writes and runs a script to join a domain.
72 73 74 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 72 def join_domain run_remote_command_runner(write_command_runner_script(generate_command_runner_script(true))) end |
#leave_domain ⇒ Object Also known as: unjoin_domain
Removes the guest machine from a Windows Domain.
Generates, writes and runs a script to leave a domain.
79 80 81 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 79 def leave_domain run_remote_command_runner(write_command_runner_script(generate_command_runner_script(false))) end |
#provision ⇒ Object
Run the Provisioner!
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 51 def provision verify_guest_capability @old_computer_name = get_guest_computer_name(machine) @machine.env.ui.say(:info, "Connecting guest machine to domain '#{config.domain}' with computer name '#{config.computer_name}'") set_credentials result = join_domain remove_command_runner_script if result restart_guest end end |
#remove_command_runner_script ⇒ Object
Remove temporary run script as it may contain sensitive plain-text credentials.
214 215 216 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 214 def remove_command_runner_script @machine.communicate.sudo("del #{WINDOWS_DOMAIN_GUEST_RUNNER_PATH}") end |
#restart_guest ⇒ Object
Restarts the Computer and waits
116 117 118 119 120 121 122 123 124 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 116 def restart_guest @machine.env.ui.say(:info, "Restarting computer for updates to take effect.") = {} [:provision_ignore_sentinel] = false @machine.action(:reload, ) begin sleep @restart_sleep_duration end until @machine.communicate.ready? end |
#run_remote_command_runner(script_path) ⇒ boolean
Runs the PowerShell script on the guest machine.
Streams the output of the command to the UI
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 222 def run_remote_command_runner(script_path) @machine.ui.info(I18n.t( "vagrant_windows_domain.running")) # A bit of an ugly dance, but this is how we get neat, colourised output and exit codes from a Powershell run last_type = nil new_line = "" error = false machine.communicate.shell.powershell("powershell -ExecutionPolicy Bypass -OutputFormat Text -file #{script_path}") do |type, data| if !data.chomp.empty? error = true if type == :stderr if [:stderr, :stdout].include?(type) color = type == :stdout ? :green : :red new_line = "\r\n" if last_type != nil and last_type != type last_type = type @machine.ui.info( new_line + data.chomp, color: color, new_line: false, prefix: false) end end end error == false end |
#set_credentials ⇒ Object
Ensure credentials are provided.
Get username/password from user if not provided as part of the config.
88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 88 def set_credentials if (config.username == nil) @logger.info("==> Requesting username as none provided") config.username = @machine.env.ui.ask("Please enter your domain username: ") end if (config.password == nil) @logger.info("==> Requesting password as none provided") config.password = @machine.env.ui.ask("Please enter your domain password (output will be hidden): ", {:echo => false}) end end |
#verify_binary(binary) ⇒ Object
Verify a binarycommand is executable on the guest machine.
134 135 136 137 138 139 140 141 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 134 def verify_binary(binary) @machine.communicate.sudo( "which #{binary}", error_class: WindowsDomainError, error_key: :binary_not_detected, domain: config.domain, binary: binary) end |
#verify_guest_capability ⇒ Object
Verify that we can call the remote operations. Required to add the computer to a Domain.
128 129 130 131 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 128 def verify_guest_capability verify_binary("Add-Computer") verify_binary("Remove-Computer") end |
#windows? ⇒ Boolean
Is the guest Windows?
261 262 263 264 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 261 def windows? # If using WinRM, we can assume we are on Windows @machine.config.vm.communicator == :winrm end |
#write_command_runner_script(script) ⇒ String
Writes the PowerShell runner script to a location on the guest.
197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/vagrant-windows-domain/provisioner.rb', line 197 def write_command_runner_script(script) guest_script_path = WINDOWS_DOMAIN_GUEST_RUNNER_PATH file = Tempfile.new(["vagrant-windows-domain-runner", "ps1"]) begin file.write(script) file.fsync file.close @machine.communicate.upload(file.path, guest_script_path) ensure file.close file.unlink end guest_script_path end |