vagrant-windows-domain 1.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 32c0962897914ab1f2665b2ee83e436403d1c7d6
4
+ data.tar.gz: 6b9f71576ad54801a1325ed828d8a04b614e186b
5
+ SHA512:
6
+ metadata.gz: a2a5bba2574096eb6dd50802d44f87b1a20e94caee7f9191dfa686cef067c16b86ca4953c97d40e3203373eed09d5eaec89d28b77a4df6ca6a5f2af473dec6b7
7
+ data.tar.gz: a15ef170cca8c7b9d8424d1e35d71d8447c3e49567fe9b74c36b6e69e31a99e7146f72dbcd9ac99679efc327a5dc19a824d4ec700e72f3c5ed6f24ef8d66f668
data/.gitignore ADDED
@@ -0,0 +1,24 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ .vagrant
24
+ .idea
data/.travis.yml ADDED
@@ -0,0 +1,19 @@
1
+ language: ruby
2
+ before_install:
3
+ - rvm @global do gem uninstall bundler --all --executables
4
+ - gem uninstall bundler --all --executables
5
+ - gem install bundler --version '< 1.7.0'
6
+ rvm:
7
+ - 2.0.0
8
+ - 2.1.0
9
+ - ruby-head
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: ruby-head
13
+ fast_finish: true
14
+ env:
15
+ matrix:
16
+ - VAGRANT_VERSION=v1.6.5
17
+ global:
18
+ secure: bs4ezY+1Wksy8hH3nymPJ3AL99mpXULVc/AIh16JetEYw1850QkX7r4gQukMlcyByKUhxucjDLid0Y+KDH5kGMM16QjrVQGhAnUQzMoLD2qPbAaxDCUqpCJtFEEQKYxJvFvEK8a5SQzAsTVG4sgABQ/MllsIIH0FjkWgFtH6050=
19
+ script: bundle exec rake test:unit
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in vagrant-windows-domain.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem "vagrant", git: "https://github.com/mitchellh/vagrant.git"
8
+ end
9
+
10
+ group :plugins do
11
+ gem "vagrant-windows-domain", path: "."
12
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Matt Fellows
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # Vagrant Windows Domain Plugin
2
+
3
+ [![Build Status](https://travis-ci.org/SEEK-Jobs/vagrant-windows-domain.svg)](https://travis-ci.org/SEEK-Jobs/vagrant-windows-domain)
4
+ [![Coverage Status](https://coveralls.io/repos/SEEK-Jobs/vagrant-windows-domain/badge.svg?branch=master)](https://coveralls.io/r/SEEK-Jobs/vagrant-windows-domain?branch=master)
5
+ [![Gem Version](https://badge.fury.io/rb/vagrant-windows-domain.svg)](http://badge.fury.io/rb/vagrant-windows-domain)
6
+
7
+ A Vagrant Plugin that makes connecting and disconnecting your Windows Vagrant box to a Windows Domain a cinch.
8
+
9
+ On a `vagrant up` - unless credentials are supplied - it will prompt the user for their domain credentials and add the guest to the domain, including restarting the guest without interfering with other provisioners.
10
+
11
+ On a `vagrant destroy`, it will do the same and remove itself from the Domain, keeping things neat-n-tidy.
12
+
13
+ ## Installation
14
+
15
+ ```vagrant plugin install vagrant-windows-domain```
16
+
17
+ ## Usage
18
+
19
+ In your Vagrantfile, add the following plugin and configure to your needs:
20
+
21
+ ```ruby
22
+ config.vm.provision :windows_domain do |domain|
23
+
24
+ # The Windows Domain to join.
25
+ #
26
+ # Setting this will result in an additional restart.
27
+ domain.domain = "domain.int"
28
+
29
+ # The new Computer Name to use when joining the domain.
30
+ #
31
+ # Uses the Rename-Computer PowerShell command. ORRRR -NewName flag??
32
+ # Specifies a new name for the computer in the new domain.
33
+ domain.computer_name "myfandangledname"
34
+
35
+ # The Username to use when authenticating against the Domain.
36
+ #
37
+ # Specifies a user account that has permission to join the computers to a new domain.
38
+ #
39
+ # If not supplied the plugin will prompt the user during provisioning to provide one.
40
+ domain.username = "me"
41
+
42
+ # The Password to use when authenticating against the Domain.
43
+ #
44
+ # Specifies the password of a user account that has permission to
45
+ # join the computers to a new domain.
46
+ #
47
+ # If not supplied the plugin will prompt the user during provisioning to provide one.
48
+ domain.password = "iprobablyshouldntusethisfield"
49
+
50
+ # The set of Advanced options to pass when joining the Domain.
51
+ #
52
+ # See (https://technet.microsoft.com/en-us/library/hh849798.aspx) for detail, these are generally not required.
53
+ domain.join_options = { "--JoinReadOnly" => "" }
54
+
55
+ # Organisational Unit path in AD.
56
+ #
57
+ # Specifies an organizational unit (OU) for the domain account.
58
+ # Enter the full distinguished name of the OU in quotation marks.
59
+ # The default value is the default OU for machine objects in the domain.
60
+ domain.ou_path = "OU=testOU,DC=domain,DC=Domain,DC=com"
61
+
62
+ # Performs an unsecure join to the specified domain.
63
+ #
64
+ # When this option is enabled username/password are not required and cannot be used.
65
+ domain.unsecure = false
66
+ end
67
+ ```
68
+ ## Example
69
+
70
+ There is a [sample](https://github.com/SEEK-Jobs/vagrant-windows-domain/tree/master/development) Vagrant setup used for development of this plugin.
71
+ This is a great real-life example to get you on your way.
72
+
73
+ ### Supported Environments
74
+
75
+ Currently the plugin supports any Windows environment with Powershell 3+ installed (2008r2, 2012r2 should work nicely).
76
+
77
+ ## Uninistallation
78
+
79
+ ```vagrant plugin uninstall vagrant-windows-domain```
80
+
81
+ ## Contributing
82
+
83
+ 1. Fork it ( https://github.com/[my-github-username]/vagrant-windows-domain/fork )
84
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
85
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
86
+ 4. Squash commits & push to the branch (`git push origin my-new-feature`)
87
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+ task :default => [:test, :quality]
4
+ # Remove 'install' task as the gem is installed to Vagrant, not to system
5
+ Rake::Task[:install].clear
6
+ namespace :test do
7
+ RSpec::Core::RakeTask.new('unit') do |task|
8
+ task.pattern = 'spec/**/*_spec.rb'
9
+ end
10
+ end
11
+ desc "Run all tests"
12
+ task :test => ['test:unit']
13
+ task :spec => :test
@@ -0,0 +1,64 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ $shell_script = <<SCRIPT
5
+ Write-Host "Hey, this happened after the restart!"
6
+ SCRIPT
7
+
8
+ # Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
9
+ VAGRANTFILE_API_VERSION = "2"
10
+
11
+ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
12
+
13
+ config.vm.box = "mfellows/windows2012r2"
14
+ config.vm.guest = :windows
15
+ config.vm.communicator = "winrm"
16
+ config.vm.network :forwarded_port, guest: 5985, host: 5985, id: "winrm", auto_correct: true
17
+
18
+ # Run Windows Domain Provisioner
19
+ config.vm.provision :windows_domain do |domain|
20
+
21
+ # The Windows Domain to join.
22
+ #
23
+ # Setting this will result in an additional restart.
24
+ domain.domain = "domain.int"
25
+
26
+ # The new Computer Name to use when joining the domain.
27
+ #
28
+ # Uses the Rename-Computer PowerShell command. ORRRR -NewName flag??
29
+ # Specifies a new name for the computer in the new domain.
30
+ domain.computer_name "myfandangledname"
31
+
32
+ # The Username to use when authenticating against the Domain.
33
+ #
34
+ # Specifies a user account that has permission to join the computers to a new domain.
35
+ domain.username = "me"
36
+
37
+ # The Password to use when authenticating against the Domain.
38
+ #
39
+ # Specifies the password of a user account that has permission to
40
+ # join the computers to a new domain.
41
+ domain.password = "iprobablyshouldntusethisfield"
42
+
43
+ # The set of Advanced options to pass when joining the Domain.
44
+ #
45
+ # See (https://technet.microsoft.com/en-us/library/hh849798.aspx) for detail.
46
+ # NOTE: If we user :computer_name from above this needs to be merged!!
47
+ domain.join_options
48
+
49
+ # Organisational Unit path in AD.
50
+ #
51
+ # Specifies an organizational unit (OU) for the domain account.
52
+ # Enter the full distinguished name of the OU in quotation marks.
53
+ # The default value is the default OU for machine objects in the domain.
54
+ domain.ou_path
55
+
56
+ # Performs an unsecure join to the specified domain.
57
+ #
58
+ # When this option is used username/password are not required
59
+ domain.unsecure
60
+ end
61
+
62
+ # Confirm that this will run after the reload from the domain provisioner!
63
+ config.vm.provision "shell", inline: $shell_script
64
+ end
@@ -0,0 +1,18 @@
1
+ require "pathname"
2
+
3
+ require "vagrant-windows-domain/plugin"
4
+
5
+ module VagrantPlugins
6
+ module WindowsDomain
7
+ lib_path = Pathname.new(File.expand_path("../vagrant-windows-domain", __FILE__))
8
+ autoload :Action, lib_path.join("action")
9
+ autoload :Errors, lib_path.join("errors")
10
+
11
+ # This returns the path to the source of this plugin.
12
+ #
13
+ # @return [Pathname]
14
+ def self.source_root
15
+ @source_root ||= Pathname.new(File.expand_path("../lib", __FILE__))
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,121 @@
1
+ require "vagrant/util/counter"
2
+ require "log4r"
3
+
4
+ module VagrantPlugins
5
+ module WindowsDomain
6
+ # The "Configuration" represents a configuration of how the WindowsDomain
7
+ # provisioner should behave: authentication mechanism etc.
8
+ class Config < Vagrant.plugin("2", :config)
9
+
10
+ # The Windows Domain to join.
11
+ #
12
+ # Setting this will result in an additional restart.
13
+ attr_accessor :domain
14
+
15
+ # The new Computer Name to use when joining the domain.
16
+ #
17
+ # Uses the Rename-Computer PowerShell command. ORRRR -NewName flag??
18
+ # Specifies a new name for the computer in the new domain.
19
+ attr_accessor :computer_name
20
+
21
+ # The Username to use when authenticating against the Domain.
22
+ #
23
+ # Specifies a user account that has permission to join the computers to a new domain.
24
+ attr_accessor :username
25
+
26
+ # The Password to use when authenticating against the Domain.
27
+ #
28
+ # Specifies the password of a user account that has permission to
29
+ # join the computers to a new domain.
30
+ attr_accessor :password
31
+
32
+ # The set of Advanced options to pass when joining the Domain.
33
+ #
34
+ # See (https://technet.microsoft.com/en-us/library/hh849798.aspx) for detail.
35
+ # NOTE: If we user :computer_name from above this needs to be merged!!
36
+ attr_accessor :join_options
37
+
38
+ # Organisational Unit path in AD.
39
+ #
40
+ # Specifies an organizational unit (OU) for the domain account.
41
+ # Enter the full distinguished name of the OU in quotation marks.
42
+ # The default value is the default OU for machine objects in the domain.
43
+ attr_accessor :ou_path
44
+
45
+ # Performs an unsecure join to the specified domain.
46
+ #
47
+ # When this option is used username/password are not required
48
+ attr_accessor :unsecure
49
+
50
+ # The current Computer Name.
51
+ #
52
+ # Used to determine whether or not we need to rename the computer
53
+ # on join. This parameter should not be manually set.
54
+ attr_accessor :old_computer_name
55
+
56
+ def initialize
57
+ super
58
+ @domain = UNSET_VALUE
59
+ @computer_name = UNSET_VALUE
60
+ @username = UNSET_VALUE
61
+ @password = UNSET_VALUE
62
+ @join_options = {}
63
+ @ou_path = UNSET_VALUE
64
+ @unsecure = UNSET_VALUE
65
+ @logger = Log4r::Logger.new("vagrant::vagrant_windows_domain")
66
+ end
67
+
68
+ # Final step of the Configuration lifecyle prior to
69
+ # validation.
70
+ #
71
+ # Ensures all attributes are set to defaults if not provided.
72
+ def finalize!
73
+ super
74
+
75
+ # Null checks
76
+ @domain = nil if @domain == UNSET_VALUE || @domain == ""
77
+ @computer_name = nil if @computer_name == UNSET_VALUE || @computer_name == ""
78
+ @username = nil if @username == UNSET_VALUE || @username == ""
79
+ @password = nil if @password == UNSET_VALUE || @password == ""
80
+ @join_options = {} if @join_options == UNSET_VALUE
81
+ @ou_path = nil if @ou_path == UNSET_VALUE
82
+ @unsecure = false if @unsecure == UNSET_VALUE
83
+ end
84
+
85
+ # Validate configuration and return a hash of errors.
86
+ #
87
+ # Validation happens after finalize!.
88
+ #
89
+ # @param [Machine] The current {Machine}
90
+ # @return [Hash] Any errors or {} if no errors found
91
+ def validate(machine)
92
+ @old_computer_name = get_guest_computer_name(machine)
93
+
94
+ errors = _detected_errors
95
+
96
+ # Need to supply one of them!
97
+ if ( (@username != nil && @password != nil) && @unsecure == true)
98
+ errors << I18n.t("vagrant_windows_domain.errors.both_credentials_provided")
99
+ end
100
+
101
+ { "windows domain provisioner" => errors }
102
+ end
103
+
104
+ # Gets the Computer Name from the guest machine
105
+ def get_guest_computer_name(machine)
106
+ computerName = ""
107
+ machine.communicate.shell.powershell("$env:COMPUTERNAME") do |type, data|
108
+ if !data.chomp.empty?
109
+ if [:stderr, :stdout].include?(type)
110
+ color = type == :stdout ? :green : :red
111
+ computerName = data.chomp
112
+ @logger.info("Detected guest computer name: #{computerName}")
113
+ end
114
+ end
115
+ end
116
+
117
+ computerName
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,17 @@
1
+ en:
2
+ vagrant_windows_domain:
3
+ already_status: |-
4
+ The machine is already %{status}.
5
+
6
+ running: |-
7
+ "Running Windows Domain Provisioner"
8
+
9
+ errors:
10
+ unsupported_platform: |-
11
+ Unsupported platform detected. Vagrant Windows Domain only works on Windows guest environments.
12
+ both_credentials_provided: |-
13
+ You must not supply a "username" and "password" if "unsecure" is set to true.
14
+ binary_not_detected: |-
15
+ "The command '%{binary} required to join/remove the guest machine from the domain '%{domain}' was not found on the guest machine"
16
+ absolute_module_path: |-
17
+ "Absolute 'module_path' not allowed. Please provide a path relative to your Vagrantfile."
@@ -0,0 +1,23 @@
1
+ require "vagrant"
2
+
3
+ module VagrantPlugins
4
+ module WindowsDomain
5
+ class Plugin < Vagrant.plugin("2")
6
+ name "DSC"
7
+ description <<-DESC
8
+ Provides support for adding and removing guest Windows machines
9
+ from a Domain.
10
+ DESC
11
+
12
+ config(:windows_domain, :provisioner) do
13
+ require_relative 'config'
14
+ Config
15
+ end
16
+
17
+ provisioner(:windows_domain) do
18
+ require_relative 'provisioner'
19
+ Provisioner
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,193 @@
1
+ require "log4r"
2
+ require 'erb'
3
+
4
+ module VagrantPlugins
5
+ module WindowsDomain
6
+ # DSC Errors namespace, including setup of locale-based error messages.
7
+ class WindowsDomainError < Vagrant::Errors::VagrantError
8
+ error_namespace("vagrant_windows_domain.errors")
9
+ I18n.load_path << File.expand_path("locales/en.yml", File.dirname(__FILE__))
10
+ end
11
+ class DSCUnsupportedOperation < WindowsDomainError
12
+ error_key(:unsupported_operation)
13
+ end
14
+
15
+ # Windows Domain Provisioner Plugin.
16
+ #
17
+ # Connects and Removes a guest Machine from a Windows Domain.
18
+ class Provisioner < Vagrant.plugin("2", :provisioner)
19
+
20
+ # Default path for storing the transient script runner
21
+ WINDOWS_DOMAIN_GUEST_RUNNER_PATH = "c:/tmp/vagrant-windows-domain-runner.ps1"
22
+
23
+ # Constructs the Provisioner Plugin.
24
+ #
25
+ # @param [Machine] machine The guest machine that is to be provisioned.
26
+ # @param [Config] config The Configuration object used by the Provisioner.
27
+ # @returns Provisioner
28
+ def initialize(machine, config)
29
+ super
30
+
31
+ @logger = Log4r::Logger.new("vagrant::provisioners::vagrant_windows_domain")
32
+ end
33
+
34
+ # Configures the Provisioner.
35
+ #
36
+ # @param [Config] root_config The default configuration from the Vagrant hierarchy.
37
+ def configure(root_config)
38
+ raise WindowsDomainError, :unsupported_platform if !windows?
39
+
40
+ verify_guest_capability
41
+ end
42
+
43
+ # Run the Provisioner!
44
+ def provision
45
+ @machine.env.ui.say(:info, "Connecting guest machine to domain '#{config.domain}' with computer name '#{config.computer_name}'")
46
+
47
+ set_credentials
48
+
49
+ join_domain
50
+
51
+ restart_guest
52
+ end
53
+
54
+ # Join the guest machine to a Windows Domain.
55
+ #
56
+ # Generates, writes and runs a script to join a domain.
57
+ def join_domain
58
+ run_remote_command_runner(write_command_runner_script(generate_command_runner_script(true)))
59
+ end
60
+
61
+ # Removes the guest machine from a Windows Domain.
62
+ #
63
+ # Generates, writes and runs a script to leave a domain.
64
+ def leave_domain
65
+ run_remote_command_runner(write_command_runner_script(generate_command_runner_script(false)))
66
+ end
67
+ alias_method :unjoin_domain, :leave_domain
68
+
69
+ # Ensure credentials are provided.
70
+ #
71
+ # Get username/password from user if not provided
72
+ # as part of the config.
73
+ def set_credentials
74
+ if (config.username == nil)
75
+ @logger.info("==> Requesting username as none provided")
76
+ config.username = @machine.env.ui.ask("Please enter your domain username: ")
77
+ end
78
+
79
+ if (config.password == nil)
80
+ @logger.info("==> Requesting password as none provided")
81
+ config.password = @machine.env.ui.ask("Please enter your domain password (output will be hidden): ", {:echo => false})
82
+ end
83
+ end
84
+
85
+ # Cleanup after a destroy action.
86
+ #
87
+ # This is the method called when destroying a machine that allows
88
+ # for any state related to the machine created by the provisioner
89
+ # to be cleaned up.
90
+ def cleanup
91
+ set_credentials
92
+ leave_domain
93
+
94
+ end
95
+
96
+ # Restarts the Computer and waits
97
+ def restart_guest
98
+ @machine.env.ui.say(:info, "Restarting computer for updates to take effect.")
99
+ options = {}
100
+ options[:provision_ignore_sentinel] = false
101
+ @machine.action(:reload, options)
102
+ begin
103
+ sleep 10
104
+ end until @machine.communicate.ready?
105
+ end
106
+
107
+ # Verify that we can call the remote operations.
108
+ # Required to add the computer to a Domain.
109
+ def verify_guest_capability
110
+ verify_binary("Add-Computer")
111
+ verify_binary("Remove-Computer")
112
+ end
113
+
114
+ # Verify a binary\command is executable on the guest machine.
115
+ def verify_binary(binary)
116
+ @machine.communicate.sudo(
117
+ "which #{binary}",
118
+ error_class: WindowsDomainError,
119
+ error_key: :binary_not_detected,
120
+ domain: config.domain,
121
+ binary: binary)
122
+ end
123
+
124
+ # Generates a PowerShell runner script from an ERB template
125
+ #
126
+ # @param [boolean] add_to_domain Whether or not to add or remove the computer to the domain (default: true).
127
+ # @return [String] The interpolated PowerShell script.
128
+ def generate_command_runner_script(add_to_domain=true)
129
+ path = File.expand_path("../templates/runner.ps1", __FILE__)
130
+
131
+ script = Vagrant::Util::TemplateRenderer.render(path, options: {
132
+ config: @config,
133
+ username: @config.username,
134
+ password: @config.password,
135
+ domain: @config.domain,
136
+ add_to_domain: add_to_domain
137
+ # parameters: @config.join_options.map { |k,v| "#{k}" + (!v.nil? ? " \"#{v}\"": '') }.join(" ")
138
+ })
139
+ end
140
+
141
+ # Writes the PowerShell runner script to a location on the guest.
142
+ #
143
+ # @param [String] script The PowerShell runner script.
144
+ # @return [String] the Path to the uploaded location on the guest machine.
145
+ def write_command_runner_script(script)
146
+ guest_script_path = WINDOWS_DOMAIN_GUEST_RUNNER_PATH
147
+ file = Tempfile.new(["vagrant-windows-domain-runner", "ps1"])
148
+ begin
149
+ file.write(script)
150
+ file.fsync
151
+ file.close
152
+ @machine.communicate.upload(file.path, guest_script_path)
153
+ ensure
154
+ file.close
155
+ file.unlink
156
+ end
157
+ guest_script_path
158
+ end
159
+
160
+ # Runs the PowerShell script on the guest machine.
161
+ def run_remote_command_runner(script_path)
162
+ command = ". '#{script_path}'"
163
+
164
+ @machine.ui.info(I18n.t(
165
+ "vagrant_windows_domain.running"))
166
+
167
+ opts = {
168
+ elevated: true,
169
+ error_key: :ssh_bad_exit_status_muted,
170
+ good_exit: 0,
171
+ shell: :powershell
172
+ }
173
+
174
+ @machine.communicate.sudo(command, opts) do |type, data|
175
+ if !data.chomp.empty?
176
+ if [:stderr, :stdout].include?(type)
177
+ color = type == :stdout ? :green : :red
178
+ @machine.ui.info(
179
+ data.chomp,
180
+ color: color, new_line: false, prefix: false)
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ # If on using WinRM, we can assume we are on Windows
187
+ def windows?
188
+ @machine.config.vm.communicator == :winrm
189
+ end
190
+
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,9 @@
1
+ $secpasswd = ConvertTo-SecureString "<%= options[:password] %>" -AsPlainText -Force
2
+ $credentials = New-Object System.Management.Automation.PSCredential ("<%= options[:username] %>", $secpasswd)
3
+
4
+ <% if options[:add_to_domain] === true %>
5
+ echo "Add-Computer"
6
+ Add-Computer -DomainName <%= options[:domain] %> -Credential $credentials -Verbose -Force #-WhatIf
7
+ <% else %>
8
+ Remove-Computer -UnjoinDomainCredential $credentials -Verbose -Force
9
+ <% end %>
@@ -0,0 +1,5 @@
1
+ module Vagrant
2
+ module WindowsDomain
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
data/spec/base.rb ADDED
@@ -0,0 +1,54 @@
1
+ shared_context "unit" do
2
+ before(:each) do
3
+ # State to store the list of registered plugins that we have to
4
+ # unregister later.
5
+ @_plugins = []
6
+
7
+ # Create a thing to store our temporary files so that they aren't
8
+ # unlinked right away.
9
+ @_temp_files = []
10
+ end
11
+
12
+ # This helper creates a temporary file and returns a Pathname
13
+ # object pointed to it.
14
+ #
15
+ # @return [Pathname]
16
+ def temporary_file(contents=nil)
17
+ f = Tempfile.new("vagrant-unit")
18
+
19
+ if contents
20
+ f.write(contents)
21
+ f.flush
22
+ end
23
+
24
+ # Store the tempfile in an instance variable so that it is not
25
+ # garbage collected, so that the tempfile is not unlinked.
26
+ @_temp_files << f
27
+
28
+ return Pathname.new(f.path)
29
+ end
30
+
31
+ # Asserts that the current (config) validation run should fail.
32
+ # Any error message is sufficient.
33
+ def assert_invalid
34
+ errors = subject.validate(machine)
35
+ if !errors.values.any? { |v| !v.empty? }
36
+ raise "No errors: #{errors.inspect}"
37
+ end
38
+ end
39
+
40
+ # Asserts that the current (config) validation should fail with a specific message.
41
+ def assert_error(error)
42
+ errors = subject.validate(machine)
43
+ raise "Error #{error} was not raised" if !errors["windows domain provisioner"].include? error
44
+ end
45
+
46
+ # Asserts that no failures should occur in the current (config) validation run.
47
+ def assert_valid
48
+ errors = subject.validate(machine)
49
+ if !errors.values.all? { |v| v.empty? }
50
+ raise "Errors: #{errors.inspect}"
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+ require 'vagrant-windows-domain/provisioner'
3
+ require 'vagrant-windows-domain/config'
4
+ require 'base'
5
+
6
+ describe VagrantPlugins::WindowsDomain::Config do
7
+ include_context "unit"
8
+ let(:instance) { described_class.new }
9
+ let(:machine) { double("machine") }
10
+
11
+ let(:root_path) { (Pathname.new(Dir.mktmpdir)).to_s }
12
+ let(:ui) { Vagrant::UI::Silent.new }
13
+ let(:machine) { double("machine", ui: ui) }
14
+ let(:env) { double("environment", root_path: root_path, ui: ui) }
15
+ let(:vm) { double ("vm") }
16
+ let(:communicator) { double ("communicator") }
17
+ let(:shell) { double ("shell") }
18
+ let(:powershell) { double ("powershell") }
19
+ let(:guest) { double ("guest") }
20
+ let(:configuration_file) { "manifests/MyWebsite.ps1" }
21
+ let(:module_path) { ["foo/modules", "foo/modules2"] }
22
+ let(:root_config) { VagrantPlugins::DSC::Config.new }
23
+ # subject { described_class.new machine, root_config }
24
+
25
+ describe "defaults (finalize!)" do
26
+
27
+ before do
28
+ env = double("environment", root_path: "/tmp/vagrant-windows-domain-path")
29
+ config = double("config")
30
+ machine.stub(config: config, env: env)
31
+ end
32
+
33
+ before { subject.finalize! }
34
+
35
+ its("domain") { should be_nil }
36
+ its("computer_name") { should eq(nil) }
37
+ its("username") { should be_nil }
38
+ its("password") { should be_nil }
39
+ its("join_options") { should eq({}) }
40
+ its("ou_path") { should be_nil }
41
+ its("unsecure") { should eq(false) }
42
+
43
+ it "should ignore empty strings" do
44
+ subject.domain = ""
45
+ subject.username = ""
46
+ subject.password = ""
47
+ subject.computer_name = ""
48
+
49
+ subject.finalize!
50
+
51
+ expect(subject.domain).to be_nil
52
+ expect(subject.computer_name).to be_nil
53
+ expect(subject.username).to be_nil
54
+ expect(subject.password).to be_nil
55
+ end
56
+ end
57
+
58
+ describe "validate settings" do
59
+ before do
60
+ env = double("environment", root_path: "/tmp/vagrant-windows-domain-path")
61
+ config = double("config")
62
+ machine.stub(config: config, env: env)
63
+ allow(machine).to receive(:communicate).and_return(communicator)
64
+ allow(communicator).to receive(:shell).and_return(shell)
65
+ allow(shell).to receive(:powershell).and_yield(:stdout, "myoldcomputername")
66
+ end
67
+
68
+ before { subject.finalize! }
69
+
70
+ it "should be invalid if either 'username' and 'password' or 'unsecure' are both provided" do
71
+ subject.username = "myusername"
72
+ subject.password = "mypassword"
73
+ subject.unsecure = true
74
+ subject.validate(machine)
75
+
76
+ assert_invalid
77
+ assert_error("You must not supply a \"username\" and \"password\" if \"unsecure\" is set to true.")
78
+ end
79
+
80
+ it "should detect the current computers' name" do
81
+ subject.validate(machine)
82
+ expect(subject.old_computer_name).to eq("myoldcomputername")
83
+ end
84
+
85
+ end
86
+
87
+ end
@@ -0,0 +1,197 @@
1
+ require 'spec_helper'
2
+ require 'vagrant-windows-domain/provisioner'
3
+ require 'vagrant-windows-domain/config'
4
+ require 'rspec/its'
5
+
6
+ describe VagrantPlugins::WindowsDomain::Provisioner do
7
+ include_context "unit"
8
+
9
+ let(:root_path) { (Pathname.new(Dir.mktmpdir)).to_s }
10
+ let(:ui) { Vagrant::UI::Silent.new }
11
+ let(:machine) { double("machine", ui: ui) }
12
+ let(:env) { double("environment", root_path: root_path, ui: ui) }
13
+ let(:vm) { double ("vm") }
14
+ let(:communicator) { double ("communicator") }
15
+ let(:shell) { double ("shell") }
16
+ let(:powershell) { double ("powershell") }
17
+ let(:guest) { double ("guest") }
18
+ let(:configuration_file) { "manifests/MyWebsite.ps1" }
19
+ let(:module_path) { ["foo/modules", "foo/modules2"] }
20
+ let(:root_config) { VagrantPlugins::WindowsDomain::Config.new }
21
+ subject { described_class.new machine, root_config }
22
+
23
+ describe "configure" do
24
+ before do
25
+ allow(machine).to receive(:root_config).and_return(root_config)
26
+ machine.stub(config: root_config, env: env)
27
+
28
+ allow(machine).to receive(:communicate).and_return(communicator)
29
+ allow(communicator).to receive(:shell).and_return(shell)
30
+ allow(shell).to receive(:powershell).with("$env:COMPUTERNAME").and_yield(:stdout, "myoldcomputername")
31
+ allow(root_config).to receive(:vm).and_return(vm)
32
+ allow(vm).to receive(:communicator).and_return(:winrm)
33
+ root_config.finalize!
34
+ root_config.validate(machine)
35
+ end
36
+
37
+ it "should confirm if the OS is Windows" do
38
+ allow(communicator).to receive(:sudo).twice
39
+ expect(subject.windows?).to eq(true)
40
+ subject.configure(root_config)
41
+ end
42
+
43
+ it "should error if the detected OS is not Windows" do
44
+ allow(vm).to receive(:communicator).and_return(:ssh)
45
+ expect { subject.configure(root_config) }.to raise_error("Unsupported platform detected. Vagrant Windows Domain only works on Windows guest environments.")
46
+ end
47
+
48
+ it "should verify the guest has the required powershell cmdlets/capabilities" do
49
+ expect(communicator).to receive(:sudo).with("which Add-Computer", {:error_class=>VagrantPlugins::WindowsDomain::WindowsDomainError, :error_key=>:binary_not_detected, :domain=>nil, :binary=>"Add-Computer"})
50
+ expect(communicator).to receive(:sudo).with("which Remove-Computer", {:error_class=>VagrantPlugins::WindowsDomain::WindowsDomainError, :error_key=>:binary_not_detected, :domain=>nil, :binary=>"Remove-Computer"})
51
+ subject.configure(root_config)
52
+ end
53
+ end
54
+
55
+ describe "provision" do
56
+
57
+ # before do
58
+ # # allow(root_config).to receive(:vm).and_return(vm)
59
+ # allow(machine).to receive(:root_config).and_return(root_config)
60
+ # allow(machine).to receive(:env).and_return(env)
61
+ # root_config.finalize!
62
+ # root_config.validate(machine)
63
+ # subject.configure(root_config)
64
+ # machine.stub(config: root_config, env: env, communicate: communicator, guest: guest)
65
+ # end
66
+
67
+ it "should join the domain" do
68
+
69
+ end
70
+
71
+ it "should restart the machine on a successful domain join" do
72
+
73
+ end
74
+
75
+ it "should not attempt to join the domain if already on it" do
76
+
77
+ end
78
+
79
+ it "should authenticate with credentials if provided" do
80
+
81
+ end
82
+
83
+ it "should prompt for credentials if not provided" do
84
+
85
+ end
86
+
87
+ it "should remove any traces of credentials once provisioning has occurred" do
88
+
89
+ end
90
+
91
+ end
92
+
93
+ describe "cleanup" do
94
+
95
+ it "should leave domain when a `vagrant destroy` is issued" do
96
+
97
+ end
98
+
99
+ end
100
+
101
+ # describe "Powershell runner script" do
102
+ # before do
103
+ # # Prevent counters messing with output in tests
104
+ # Vagrant::Util::Counter.class_eval do
105
+ # def get_and_update_counter(name=nil) 1 end
106
+ # end
107
+
108
+ # allow(machine).to receive(:root_config).and_return(root_config)
109
+ # root_config.configuration_file = configuration_file
110
+ # machine.stub(config: root_config, env: env)
111
+ # root_config.module_path = module_path
112
+ # root_config.configuration_file = configuration_file
113
+ # root_config.finalize!
114
+ # root_config.validate(machine)
115
+ # subject.configure(root_config)
116
+
117
+ # end
118
+
119
+ # context "with default parameters" do
120
+ # it "should generate a valid powershell command" do
121
+ # script = subject.generate_dsc_runner_script
122
+ # expect_script = "#
123
+ # # DSC Runner.
124
+ # #
125
+ # # Bootstraps the DSC environment, sets up configuration data
126
+ # # and runs the DSC Configuration.
127
+ # #
128
+ # #
129
+
130
+ # # Set the local PowerShell Module environment path
131
+ # $absoluteModulePaths = [string]::Join(\";\", (\"/tmp/vagrant-windows-domain-1/modules-0;/tmp/vagrant-windows-domain-1/modules-1\".Split(\";\") | ForEach-Object { $_ | Resolve-Path }))
132
+
133
+ # echo \"Adding to path: $absoluteModulePaths\"
134
+ # $env:PSModulePath=\"$absoluteModulePaths;${env:PSModulePath}\"
135
+ # (\"/tmp/vagrant-windows-domain-1/modules-0;/tmp/vagrant-windows-domain-1/modules-1\".Split(\";\") | ForEach-Object { gci -Recurse $_ | ForEach-Object { Unblock-File $_.FullName} })
136
+
137
+ # $script = $(Join-Path \"/tmp/vagrant-windows-domain-1\" \"manifests/MyWebsite.ps1\" -Resolve)
138
+ # echo \"PSModulePath Configured: ${env:PSModulePath}\"
139
+ # echo \"Running Configuration file: ${script}\"
140
+
141
+ # # Generate the MOF file, only if a MOF path not already provided.
142
+ # # Import the Manifest
143
+ # . $script
144
+
145
+ # cd \"/tmp/vagrant-windows-domain-1\"
146
+ # $StagingPath = $(Join-Path \"/tmp/vagrant-windows-domain-1\" \"staging\")
147
+ # $response = MyWebsite -OutputPath $StagingPath 4>&1 5>&1 | Out-String
148
+
149
+ # # Start a DSC Configuration run
150
+ # $response += Start-DscConfiguration -Force -Wait -Verbose -Path $StagingPath 4>&1 5>&1 | Out-String
151
+ # $response"
152
+
153
+ # expect(script).to eq(expect_script)
154
+ # end
155
+ # end
156
+
157
+ # end
158
+
159
+ # describe "write DSC Runner script" do
160
+ # it "should upload the customised DSC runner to the guest" do
161
+ # script = "myscript"
162
+ # path = "/local/runner/path"
163
+ # guest_path = "c:/tmp/vagrant-windows-domain-runner.ps1"
164
+ # machine.stub(config: root_config, env: env, communicate: communicator)
165
+ # file = double("file")
166
+ # allow(file).to receive(:path).and_return(path)
167
+ # allow(Tempfile).to receive(:new) { file }
168
+ # expect(file).to receive(:write).with(script)
169
+ # expect(file).to receive(:fsync)
170
+ # expect(file).to receive(:close).exactly(2).times
171
+ # expect(file).to receive(:unlink)
172
+ # expect(communicator).to receive(:upload).with(path, guest_path)
173
+ # res = subject.write_dsc_runner_script(script)
174
+ # expect(res.to_s).to eq(guest_path)
175
+ # end
176
+ # end
177
+
178
+ # describe "Apply DSC" do
179
+ # it "should invoke the DSC Runner and notify the User of provisioning status" do
180
+ # expect(ui).to receive(:info).with(any_args).once
181
+ # expect(ui).to receive(:info).with("provisioned!", {color: :green, new_line: false, prefix: false}).once
182
+ # allow(machine).to receive(:communicate).and_return(communicator)
183
+ # expect(communicator).to receive(:sudo).with('. ' + "'c:/tmp/vagrant-windows-domain-runner.ps1'",{:elevated=>true, :error_key=>:ssh_bad_exit_status_muted, :good_exit=>0, :shell=>:powershell}).and_yield(:stdout, "provisioned!")
184
+
185
+ # subject.run_dsc_apply
186
+ # end
187
+
188
+ # it "should show error output in red" do
189
+ # expect(ui).to receive(:info).with(any_args).once
190
+ # expect(ui).to receive(:info).with("provisioned!", {color: :red, new_line: false, prefix: false}).once
191
+ # allow(machine).to receive(:communicate).and_return(communicator)
192
+ # expect(communicator).to receive(:sudo).with('. ' + "'c:/tmp/vagrant-windows-domain-runner.ps1'",{:elevated=>true, :error_key=>:ssh_bad_exit_status_muted, :good_exit=>0, :shell=>:powershell}).and_yield(:stderr, "provisioned!")
193
+
194
+ # subject.run_dsc_apply
195
+ # end
196
+ # end
197
+ end
@@ -0,0 +1,25 @@
1
+ require 'simplecov'
2
+ require 'coveralls'
3
+
4
+ require 'vagrant-windows-domain/version'
5
+ require 'vagrant-windows-domain/plugin'
6
+ require 'rspec/its'
7
+ require 'base'
8
+
9
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
10
+ SimpleCov::Formatter::HTMLFormatter,
11
+ Coveralls::SimpleCov::Formatter
12
+ ]
13
+
14
+ SimpleCov.start do
15
+ coverage_dir('tmp/coverage')
16
+ add_filter '/spec/'
17
+ end
18
+
19
+ RSpec.configure do |config|
20
+ config.expect_with :rspec do |c|
21
+ c.syntax = :expect
22
+ end
23
+ config.color = true
24
+ config.tty = true
25
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'vagrant-windows-domain/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "vagrant-windows-domain"
8
+ spec.version = Vagrant::WindowsDomain::VERSION
9
+ spec.authors = ["Matt Fellows"]
10
+ spec.email = ["matt.fellows@onegeek.com.au"]
11
+ spec.summary = "Windows Domain Provisioner for Vagrant"
12
+ spec.description = "Adds and Removes Windows Guests from a Windows Domain, as part of the standard machine lifecycle."
13
+ spec.homepage = "https://github.com/SEEK-Jobs/vagrant-windows-domain"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "rake", '~> 10.3', '>= 10.3.0'
22
+ spec.add_development_dependency "bundler", "~> 1.6", '>= 1.6.0'
23
+ spec.add_development_dependency "coveralls", "~> 0.7.1", '>= 0.7.1'
24
+ spec.add_development_dependency "rspec-core", '~> 3.1', '>= 3.1.0'
25
+ spec.add_development_dependency "rspec-expectations", '~> 3.1', '>= 3.1.0'
26
+ spec.add_development_dependency "rspec-mocks", '~> 3.1', '>= 3.1.0'
27
+ spec.add_development_dependency "rspec-its", "~> 1.0.1", '>= 1.0.0'
28
+ end
metadata ADDED
@@ -0,0 +1,208 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vagrant-windows-domain
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Matt Fellows
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '10.3'
20
+ - - '>='
21
+ - !ruby/object:Gem::Version
22
+ version: 10.3.0
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '10.3'
30
+ - - '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 10.3.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ~>
38
+ - !ruby/object:Gem::Version
39
+ version: '1.6'
40
+ - - '>='
41
+ - !ruby/object:Gem::Version
42
+ version: 1.6.0
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ~>
48
+ - !ruby/object:Gem::Version
49
+ version: '1.6'
50
+ - - '>='
51
+ - !ruby/object:Gem::Version
52
+ version: 1.6.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: coveralls
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ~>
58
+ - !ruby/object:Gem::Version
59
+ version: 0.7.1
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: 0.7.1
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 0.7.1
70
+ - - '>='
71
+ - !ruby/object:Gem::Version
72
+ version: 0.7.1
73
+ - !ruby/object:Gem::Dependency
74
+ name: rspec-core
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ~>
78
+ - !ruby/object:Gem::Version
79
+ version: '3.1'
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: 3.1.0
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '3.1'
90
+ - - '>='
91
+ - !ruby/object:Gem::Version
92
+ version: 3.1.0
93
+ - !ruby/object:Gem::Dependency
94
+ name: rspec-expectations
95
+ requirement: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ~>
98
+ - !ruby/object:Gem::Version
99
+ version: '3.1'
100
+ - - '>='
101
+ - !ruby/object:Gem::Version
102
+ version: 3.1.0
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: '3.1'
110
+ - - '>='
111
+ - !ruby/object:Gem::Version
112
+ version: 3.1.0
113
+ - !ruby/object:Gem::Dependency
114
+ name: rspec-mocks
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ~>
118
+ - !ruby/object:Gem::Version
119
+ version: '3.1'
120
+ - - '>='
121
+ - !ruby/object:Gem::Version
122
+ version: 3.1.0
123
+ type: :development
124
+ prerelease: false
125
+ version_requirements: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ~>
128
+ - !ruby/object:Gem::Version
129
+ version: '3.1'
130
+ - - '>='
131
+ - !ruby/object:Gem::Version
132
+ version: 3.1.0
133
+ - !ruby/object:Gem::Dependency
134
+ name: rspec-its
135
+ requirement: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ~>
138
+ - !ruby/object:Gem::Version
139
+ version: 1.0.1
140
+ - - '>='
141
+ - !ruby/object:Gem::Version
142
+ version: 1.0.0
143
+ type: :development
144
+ prerelease: false
145
+ version_requirements: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: 1.0.1
150
+ - - '>='
151
+ - !ruby/object:Gem::Version
152
+ version: 1.0.0
153
+ description: Adds and Removes Windows Guests from a Windows Domain, as part of the
154
+ standard machine lifecycle.
155
+ email:
156
+ - matt.fellows@onegeek.com.au
157
+ executables: []
158
+ extensions: []
159
+ extra_rdoc_files: []
160
+ files:
161
+ - .gitignore
162
+ - .travis.yml
163
+ - Gemfile
164
+ - LICENSE.txt
165
+ - README.md
166
+ - Rakefile
167
+ - development/Vagrantfile
168
+ - lib/vagrant-windows-domain.rb
169
+ - lib/vagrant-windows-domain/config.rb
170
+ - lib/vagrant-windows-domain/locales/en.yml
171
+ - lib/vagrant-windows-domain/plugin.rb
172
+ - lib/vagrant-windows-domain/provisioner.rb
173
+ - lib/vagrant-windows-domain/templates/runner.ps1.erb
174
+ - lib/vagrant-windows-domain/version.rb
175
+ - spec/base.rb
176
+ - spec/provisioner/config_spec.rb
177
+ - spec/provisioner/provisioner_spec.rb
178
+ - spec/spec_helper.rb
179
+ - vagrant-windows-domain.gemspec
180
+ homepage: https://github.com/SEEK-Jobs/vagrant-windows-domain
181
+ licenses:
182
+ - MIT
183
+ metadata: {}
184
+ post_install_message:
185
+ rdoc_options: []
186
+ require_paths:
187
+ - lib
188
+ required_ruby_version: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - '>='
191
+ - !ruby/object:Gem::Version
192
+ version: '0'
193
+ required_rubygems_version: !ruby/object:Gem::Requirement
194
+ requirements:
195
+ - - '>='
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ requirements: []
199
+ rubyforge_project:
200
+ rubygems_version: 2.4.1
201
+ signing_key:
202
+ specification_version: 4
203
+ summary: Windows Domain Provisioner for Vagrant
204
+ test_files:
205
+ - spec/base.rb
206
+ - spec/provisioner/config_spec.rb
207
+ - spec/provisioner/provisioner_spec.rb
208
+ - spec/spec_helper.rb