vagrant-azure 1.1.1 → 1.2.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 +4 -4
- data/Gemfile +1 -1
- data/README.md +88 -48
- data/lib/vagrant-azure/action.rb +2 -3
- data/lib/vagrant-azure/action/os_type.rb +1 -1
- data/lib/vagrant-azure/action/read_ssh_info.rb +2 -2
- data/lib/vagrant-azure/action/read_winrm_info.rb +14 -14
- data/lib/vagrant-azure/action/run_instance.rb +30 -33
- data/lib/vagrant-azure/config.rb +34 -40
- data/lib/vagrant-azure/monkey_patch/winrm.rb +4 -69
- data/lib/vagrant-azure/plugin.rb +0 -2
- data/lib/vagrant-azure/version.rb +1 -1
- data/vagrant-azure.gemspec +19 -51
- metadata +9 -13
- data/lib/vagrant-azure/action/provision.rb +0 -42
- data/lib/vagrant-azure/action/wait_for_communicate.rb +0 -39
- data/lib/vagrant-azure/monkey_patch/azure.rb +0 -46
- data/lib/vagrant-azure/provisioner/chef-solo.rb +0 -178
- data/lib/vagrant-azure/provisioner/puppet.rb +0 -116
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a28028fe5fa394ab6535f78e67f8ade729fd709
|
4
|
+
data.tar.gz: 0f5fafc045638222719f0102af678a03707b82b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef18dc3206b2267af138b30147492266cb4ad08896365606c530bcb65d5d0c9dcbd59719bb9d53ad962a7a9ec084869111c9f56a9608f8317715d3ab3da6dfcb
|
7
|
+
data.tar.gz: 7d65d14e639d694ec264b9b4d3cadb69c2e0fb5fda34db3e06fc232822f3dffb0570c824b35089bcb7e5d500c925df719401aff6b6a01cea7c8cf136f8675716
|
data/Gemfile
CHANGED
@@ -12,7 +12,7 @@ group :development do
|
|
12
12
|
# We depend on Vagrant for development, but we don't add it as a
|
13
13
|
# gem dependency because we expect to be installed within the
|
14
14
|
# Vagrant environment itself using `vagrant plugin`.
|
15
|
-
gem 'vagrant', git: 'git://github.com/mitchellh/vagrant.git', tag: 'v1.7.
|
15
|
+
gem 'vagrant', git: 'git://github.com/mitchellh/vagrant.git', tag: 'v1.7.3'
|
16
16
|
end
|
17
17
|
|
18
18
|
group :plugins do
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|

|
4
4
|
|
5
|
-
This is a [Vagrant](http://www.vagrantup.com) 1.
|
5
|
+
This is a [Vagrant](http://www.vagrantup.com) 1.7.3+ plugin that adds [Microsoft Azure](https://azure.microsoft.com)
|
6
6
|
provider to Vagrant, allowing Vagrant to control and provision machines in Microsoft Azure.
|
7
7
|
|
8
8
|
## Usage
|
@@ -34,37 +34,36 @@ Now edit your ```Vagrantfile``` as shown below and provide all the values as exp
|
|
34
34
|
```ruby
|
35
35
|
Vagrant.configure('2') do |config|
|
36
36
|
config.vm.box = 'azure'
|
37
|
-
|
38
|
-
config.vm.provider :azure do |azure|
|
37
|
+
|
38
|
+
config.vm.provider :azure do |azure, override|
|
39
|
+
# Mandatory Settings
|
39
40
|
azure.mgmt_certificate = 'YOUR AZURE MANAGEMENT CERTIFICATE'
|
40
41
|
azure.mgmt_endpoint = 'https://management.core.windows.net'
|
41
42
|
azure.subscription_id = 'YOUR AZURE SUBSCRIPTION ID'
|
42
|
-
azure.storage_acct_name = 'NAME OF YOUR STORAGE ACCOUNT' # optional. A new one will be generated if not provided.
|
43
|
-
|
44
43
|
azure.vm_image = 'NAME OF THE IMAGE TO USE'
|
45
|
-
azure.vm_user = 'PROVIDE A USERNAME' # defaults to 'vagrant' if not provided
|
46
|
-
azure.vm_password = 'PROVIDE A VALID PASSWORD' # min 8 characters. should contain a lower case letter, an uppercase letter, a number and a special character
|
47
|
-
|
48
44
|
azure.vm_name = 'PROVIDE A NAME FOR YOUR VIRTUAL MACHINE' # max 15 characters. contains letters, number and hyphens. can start with letters and can end with letters and numbers
|
45
|
+
|
46
|
+
# vm_password is optional when specifying the private_key_file with Linux VMs
|
47
|
+
# When building a Windows VM and using WinRM this setting is used to authenticate via WinRM (PowerShell Remoting)
|
48
|
+
azure.vm_password = 'PROVIDE A VALID PASSWORD' # min 8 characters. should contain a lower case letter, an uppercase letter, a number and a special character
|
49
|
+
|
50
|
+
# Optional Settings
|
51
|
+
azure.storage_acct_name = 'NAME OF YOUR STORAGE ACCOUNT' # optional. A new one will be generated if not provided.
|
52
|
+
azure.vm_user = 'PROVIDE A USERNAME' # defaults to 'vagrant' if not provided
|
49
53
|
azure.cloud_service_name = 'PROVIDE A NAME FOR YOUR CLOUD SERVICE' # same as vm_name. leave blank to auto-generate
|
50
54
|
azure.deployment_name = 'PROVIDE A NAME FOR YOUR DEPLOYMENT' # defaults to cloud_service_name
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
azure.tcp_endpoints = '3389:53389' # opens the Remote Desktop internal port that listens on public port 53389. Without this, you cannot RDP to a Windows VM.
|
55
|
+
azure.vm_location = 'PROVIDE A LOCATION FOR VM' # e.g., West US
|
56
|
+
|
57
|
+
# Optional *Nix Settings
|
58
|
+
azure.ssh_port = 'A VALID PUBLIC PORT' # defaults to 22
|
59
|
+
azure.private_key_file = 'Path to your ssh private key file (~/.ssh/id_rsa) to use for passwordless auth. If the id_rsa file is password protected, you will be prompted for the password.'
|
60
|
+
|
61
|
+
# Optional Windows Settings
|
62
|
+
azure.winrm_transport = [ 'http', 'https' ] # this will open up winrm ports on both http (5985) and http (5986) ports
|
63
|
+
azure.winrm_https_port = 'A VALID PUBLIC PORT' # customize the winrm https port, instead of 5986
|
64
|
+
azure.winrm_http_port = 'A VALID PUBLIC PORT' # customize the winrm http port, insted of 5985
|
65
|
+
azure.tcp_endpoints = '3389:53389' # opens the Remote Desktop internal port that listens on public port 53389. Without this, you cannot RDP to a Windows VM.
|
64
66
|
end
|
65
|
-
|
66
|
-
config.ssh.username = 'YOUR USERNAME' # the one used to create the VM
|
67
|
-
config.ssh.password = 'YOUR PASSWORD' # the one used to create the VM
|
68
67
|
end
|
69
68
|
```
|
70
69
|
|
@@ -82,37 +81,40 @@ Normally, a lot of this options, e.g., ```vm_image```, will be embedded in a box
|
|
82
81
|
|
83
82
|
## Azure Boxes
|
84
83
|
|
85
|
-
The vagrant-azure plugin provides the ability to use ```
|
84
|
+
The vagrant-azure plugin provides the ability to use ```Azure``` boxes with Vagrant. Please see the example box provided in [example_box/ directory](https://github.com/msopentech/vagrant-azure/tree/master/example_box) and follow the instructions there to build an ```azure``` box.
|
86
85
|
|
87
86
|
Please see [Vagrant Docs](http://docs.vagrantup.com/v2/) for more details.
|
88
87
|
|
89
88
|
## Configuration
|
90
89
|
|
91
|
-
The vagrant-azure provide exposes a few Azure specific
|
90
|
+
The vagrant-azure provide exposes a few Azure specific configuration options:
|
92
91
|
|
93
|
-
|
92
|
+
### Mandatory
|
93
|
+
|
94
|
+
* `mgmt_certificate` - Your Azure Management certificate which has been uploaded to the Azure portal for your account. Provide [PEM file path](#pem-generation), PFX file path or raw string.
|
94
95
|
* `mgmt_endpoint` - Azure Management endpoint. `https://management.core.windows.net`
|
95
96
|
* `subscription_id` - Your Azure Subscription ID.
|
96
97
|
* `storage_acct_name` - The Storage account to use when creating VMs.
|
98
|
+
* `vm_name` - The name of the created VM.
|
99
|
+
|
100
|
+
### Optional
|
101
|
+
|
97
102
|
* `vm_user` - The username to create the VM with. Defaults to `vagrant`.
|
98
|
-
* `vm_password` - The password to set for the user created with the VM.
|
103
|
+
* `vm_password` - The password to set for the user created with the VM. This will override the private_key_file setting.
|
99
104
|
* `vm_image` - The name of the image to be used when creating the VM.
|
100
|
-
* `
|
101
|
-
* `vm_size` - The size of the created VM.
|
105
|
+
* `vm_size` - The size of the created VM. Use an of the Azure VM Sizes.
|
102
106
|
* `vm_virtual_network_name` - The name of a virtual network to connect to
|
103
107
|
* `cloud_service_name` - The name of the cloud service under which to create the VM.
|
104
108
|
* `deployment_name` - The name to give the deployment in the cloud service and add the VM to.
|
105
109
|
* `vm_location` - The location to create the cloud service, storage account.
|
106
|
-
* `private_key_file` - The private key file to use for SSH
|
107
|
-
* `certificate_file` - The certificate file to use for SSH and if WinRM is enabled over HTTP/S.
|
110
|
+
* `private_key_file` - The private key file to use for SSH (~/.ssh/id_rsa) or a [PEM file](#pem-generation).
|
108
111
|
* `ssh_port` - To map the internal SSH port 22 to a different public port.
|
109
112
|
* `winrm_transport` - Enables or disables WinRm. Allowed values are `http` and `https`.
|
110
|
-
* `winrm_https_port` To map the internal WinRM https port 5986 to a different public port.
|
111
|
-
* `winrm_http_port` To map the internal WinRM http port 5985 to a different public port.
|
113
|
+
* `winrm_https_port` To map the internal WinRM https port 5986 to a different public port. Must be non-empty.
|
114
|
+
* `winrm_http_port` To map the internal WinRM http port 5985 to a different public port. Must be non-empty.
|
112
115
|
* `tcp_endpoints` - To open any additional ports. E.g., `80` opens port `80` and `80,3389:53389` opens port `80` and `3389`. Also maps the interal port `3389` to public port `53389`
|
113
|
-
*
|
114
116
|
|
115
|
-
|
117
|
+
### Certificate Generation on Windows
|
116
118
|
We will use `makecert.exe` distributed as part of the in the Windows 7 SDK. The following commands will create the required certificates and insert them into the current user’s personal store.
|
117
119
|
|
118
120
|
* makecert.exe -r -pe -a sha1 -n "CN=My Azure Management Certificate"
|
@@ -123,19 +125,56 @@ and AES Cryptographic Provider" -sy 24
|
|
123
125
|
|
124
126
|
* makecert.exe -r -pe -a sha1 -n "CN=My Azure SSL Certificate" -ss My -sr CurrentUser -len 2048 -sky exchange -sp "Microsoft Enhanced RSA and AES Cryptographic Provider" -sy 24
|
125
127
|
|
126
|
-
In order to have more details with images in Windows
|
128
|
+
(In order to have more details with images in Windows)[http://blogs.msdn.com/b/cclayton/archive/2012/03/21/windows-azure-and-x509-certificates.aspx]
|
129
|
+
|
130
|
+
### Get Started with Publish Settings
|
131
|
+
|
132
|
+
* To create a pfx from the publishsettings, simply download the publishsettings file for your subscription
|
133
|
+
[https://manage.windowsazure.com/publishsettings](https://manage.windowsazure.com/publishsettings/index?client=powershell). Make sure you have this gem installed and
|
134
|
+
run `pfxer --in [path to your .publishsettings file]`. This will create a .pfx from your publish settings file which can
|
135
|
+
be supplied as a cert parameter for Service Management Commands.
|
136
|
+
|
137
|
+
### Get Started with OpenSSL
|
138
|
+
|
139
|
+
* Using the following openssl commands to create a cert and upload to Azure Management
|
140
|
+
* Generate public and private `openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout cert.pem -out cert.pem`
|
141
|
+
* Generate public .cer for Azure upload `openssl x509 -inform pem -in cert.pem -outform der -out mgmt.cer`
|
142
|
+
* Upload the `mgmt.cer` to Azure Management through [https://management.azure.com](https://management.azure.com)
|
143
|
+
* Use cert.pem as your cert parameter for Service Management Commands.
|
144
|
+
|
145
|
+
### Using your .pem certificate
|
146
|
+
|
147
|
+
Vagrant-Azure expects you to use a .pem management certificate as shown below:
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
Vagrant.configure('2') do |config|
|
151
|
+
config.vm.box = 'azure'
|
152
|
+
|
153
|
+
config.vm.provider :azure do |azure|
|
154
|
+
azure.mgmt_certificate = "#{file_location_of_your_dot_pem}"
|
155
|
+
```
|
156
|
+
|
157
|
+
## Create Virtual Network
|
158
|
+
|
159
|
+
In order to use vagrant-azure's `vm_virtual_network_name` support, create virtual networks using
|
160
|
+
[Azure's Command Line Interface](http://azure.microsoft.com/en-us/documentation/articles/virtual-machines-command-line-tools/):
|
161
|
+
|
162
|
+
azure account download
|
163
|
+
azure network vnet create --vnet "vnet-name" --location "West US" --create-new-affinity-group
|
127
164
|
|
128
|
-
As Windows Azure is constantly being updated, the Windows Azure images used in this tutorial might be out-of-date.
|
129
165
|
|
130
166
|
## New Commands for `azure` provider
|
131
167
|
|
132
168
|
The `azure` provider introduces the following new `vagrant` commands.
|
133
169
|
|
134
170
|
* `rdp` - To connect to a Windows VM using RDP. E.g.,
|
171
|
+
* `powershell` - To execute remote powershell commands on a Windows VM using WinRM.
|
135
172
|
```
|
136
|
-
|
173
|
+
> vagrant up --provider=azure
|
137
174
|
...
|
138
|
-
|
175
|
+
> vagrant rdp
|
176
|
+
...
|
177
|
+
> vagrant powershell
|
139
178
|
```
|
140
179
|
|
141
180
|
|
@@ -147,10 +186,11 @@ Example Multi Machine Vagrantfile (for building out 3 Windows Virtual Machines)
|
|
147
186
|
```ruby
|
148
187
|
|
149
188
|
Vagrant.configure('2') do |config|
|
150
|
-
config.vm.box = 'azure'
|
151
189
|
config.vm.boot_timeout = 1000
|
152
190
|
|
153
|
-
do_common_azure_stuff = Proc.new do |azure|
|
191
|
+
do_common_azure_stuff = Proc.new do |azure, override|
|
192
|
+
override.config.vm.box = 'azure'
|
193
|
+
|
154
194
|
azure.mgmt_certificate = 'YOUR AZURE MANAGEMENT CERTIFICATE'
|
155
195
|
azure.mgmt_endpoint = 'https://management.core.windows.net'
|
156
196
|
azure.subscription_id = 'YOUR AZURE SUBSCRIPTION ID'
|
@@ -169,29 +209,29 @@ Vagrant.configure('2') do |config|
|
|
169
209
|
end
|
170
210
|
|
171
211
|
config.vm.define 'first' do |cfg|
|
172
|
-
|
212
|
+
cfg.vm.provider :azure do |azure, override|
|
213
|
+
do_common_azure_stuff.call azure, override
|
173
214
|
azure.vm_name = 'PROVIDE A NAME FOR YOUR VIRTUAL MACHINE'
|
174
215
|
azure.tcp_endpoints = '3389:53389' # opens the Remote Desktop internal port that listens on public port 53389. Without this, you cannot RDP to a Windows VM.
|
175
216
|
azure.winrm_https_port = 5986
|
176
|
-
do_common_azure_stuff.call azure
|
177
217
|
end
|
178
218
|
end
|
179
219
|
|
180
220
|
config.vm.define 'second' do |cfg|
|
181
|
-
cfg.vm.provider :azure do |azure|
|
221
|
+
cfg.vm.provider :azure do |azure, override|
|
222
|
+
do_common_azure_stuff.call azure, override
|
182
223
|
azure.vm_name = 'PROVIDE A NAME FOR YOUR VIRTUAL MACHINE'
|
183
224
|
azure.tcp_endpoints = '3389:53390'
|
184
225
|
azure.winrm_https_port = 5987
|
185
|
-
do_common_azure_stuff.call azure
|
186
226
|
end
|
187
227
|
end
|
188
228
|
|
189
229
|
config.vm.define 'third' do |cfg|
|
190
|
-
cfg.vm.provider :azure do |azure|
|
230
|
+
cfg.vm.provider :azure do |azure, override|
|
231
|
+
do_common_azure_stuff.call azure, override
|
191
232
|
azure.vm_name = 'PROVIDE A NAME FOR YOUR VIRTUAL MACHINE'
|
192
233
|
azure.tcp_endpoints = '3389:53391'
|
193
234
|
azure.winrm_https_port = 5988
|
194
|
-
do_common_azure_stuff.call azure
|
195
235
|
end
|
196
236
|
end
|
197
237
|
|
data/lib/vagrant-azure/action.rb
CHANGED
@@ -6,6 +6,7 @@
|
|
6
6
|
require 'pathname'
|
7
7
|
|
8
8
|
require 'vagrant/action/builder'
|
9
|
+
require 'vagrant/action/builtin/wait_for_communicator'
|
9
10
|
|
10
11
|
module VagrantPlugins
|
11
12
|
module WinAzure
|
@@ -186,7 +187,7 @@ module VagrantPlugins
|
|
186
187
|
'vagrant_azure.vm_started', :name => $`
|
187
188
|
)
|
188
189
|
b1.use action_read_winrm_info
|
189
|
-
b1.use
|
190
|
+
b1.use WaitForCommunicator
|
190
191
|
b1.use action_provision
|
191
192
|
end
|
192
193
|
end
|
@@ -251,7 +252,6 @@ module VagrantPlugins
|
|
251
252
|
autoload :ReadSSHInfo, action_root.join('read_ssh_info')
|
252
253
|
autoload :ReadWinrmInfo, action_root.join('read_winrm_info')
|
253
254
|
autoload :PowerShellRun, action_root.join('powershell_run')
|
254
|
-
autoload :Provision, action_root.join('provision')
|
255
255
|
autoload :OSType, action_root.join('os_type')
|
256
256
|
autoload :ReadState, action_root.join('read_state')
|
257
257
|
autoload :RestartVM, action_root.join('restart_vm')
|
@@ -261,7 +261,6 @@ module VagrantPlugins
|
|
261
261
|
autoload :SyncFolders, action_root.join('sync_folders')
|
262
262
|
autoload :TerminateInstance, action_root.join('terminate_instance')
|
263
263
|
autoload :WaitForState, action_root.join('wait_for_state')
|
264
|
-
autoload :WaitForCommunicate, action_root.join('wait_for_communicate')
|
265
264
|
end
|
266
265
|
end
|
267
266
|
end
|
@@ -18,7 +18,7 @@ module VagrantPlugins
|
|
18
18
|
|
19
19
|
unless env[:machine].config.vm.guest
|
20
20
|
env[:ui].info 'Determining OS Type By Image'
|
21
|
-
guest_os_type = env[:azure_vm_service].send(:
|
21
|
+
guest_os_type = env[:azure_vm_service].send(:get_image, env[:machine].provider_config.vm_image).os_type
|
22
22
|
env[:machine].config.vm.guest = guest_os_type && guest_os_type.downcase.to_sym
|
23
23
|
if env[:machine].config.vm.guest == :windows && env[:machine].config.vm.communicator.nil?
|
24
24
|
env[:machine].config.vm.communicator = :winrm
|
@@ -16,14 +16,14 @@ module VagrantPlugins
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def call(env)
|
19
|
-
env[:ui].
|
19
|
+
env[:ui].detail "Looking for local port #{@port}"
|
20
20
|
|
21
21
|
env[:machine_ssh_info] = read_ssh_info(
|
22
22
|
env[:azure_vm_service],
|
23
23
|
env[:machine]
|
24
24
|
)
|
25
25
|
|
26
|
-
env[:ui].
|
26
|
+
env[:ui].detail "Found port mapping #{env[:machine_ssh_info][:port]} --> #{@port}"
|
27
27
|
|
28
28
|
@app.call(env)
|
29
29
|
end
|
@@ -16,14 +16,9 @@ module VagrantPlugins
|
|
16
16
|
|
17
17
|
def call(env)
|
18
18
|
if env[:machine].config.vm.guest == :windows
|
19
|
-
env[:ui].
|
20
|
-
|
21
|
-
env[:
|
22
|
-
env[:azure_vm_service],
|
23
|
-
env[:machine]
|
24
|
-
)
|
25
|
-
|
26
|
-
env[:ui].info "Found public port #{env[:machine_winrm_info][:port]}"
|
19
|
+
env[:ui].detail 'Looking for WinRM'
|
20
|
+
env[:machine_winrm_info] = read_winrm_info(env[:azure_vm_service], env[:machine])
|
21
|
+
env[:ui].detail "Found public port #{env[:machine_winrm_info][:port]}"
|
27
22
|
end
|
28
23
|
|
29
24
|
@app.call(env)
|
@@ -41,14 +36,19 @@ module VagrantPlugins
|
|
41
36
|
return nil
|
42
37
|
end
|
43
38
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
39
|
+
types = %w(PowerShell WinRm-Http)
|
40
|
+
|
41
|
+
endpoint = vm.tcp_endpoints.reject { |i| !types.include?(i[:name]) }.sort{ |i| i[:name] }.first
|
42
|
+
if endpoint
|
43
|
+
machine.config.winrm.host = "#{vm.cloud_service_name}.cloudapp.net"
|
44
|
+
machine.config.winrm.port = endpoint[:public_port]
|
45
|
+
|
46
|
+
if endpoint[:name] == types[0] # if it's PowerShell, then it's over https so use ssl (cert is self signed)
|
47
|
+
machine.config.winrm.ssl_peer_verification = false
|
48
|
+
machine.config.winrm.transport = :ssl
|
49
49
|
end
|
50
|
+
return {:host => "#{vm.cloud_service_name}.cloudapp.net", :port => endpoint[:public_port]}
|
50
51
|
end
|
51
|
-
|
52
52
|
nil
|
53
53
|
end
|
54
54
|
end
|
@@ -6,6 +6,7 @@
|
|
6
6
|
require 'log4r'
|
7
7
|
require 'json'
|
8
8
|
require 'azure'
|
9
|
+
require 'openssl'
|
9
10
|
|
10
11
|
require 'vagrant/util/retryable'
|
11
12
|
|
@@ -25,46 +26,42 @@ module VagrantPlugins
|
|
25
26
|
|
26
27
|
# Add the mandatory parameters and options
|
27
28
|
params = {
|
28
|
-
|
29
|
-
|
30
|
-
|
29
|
+
vm_name: config.vm_name,
|
30
|
+
vm_user: config.vm_user,
|
31
|
+
image: config.vm_image
|
31
32
|
}
|
32
33
|
|
33
34
|
options = {
|
34
|
-
|
35
|
+
cloud_service_name: config.cloud_service_name
|
35
36
|
}
|
36
37
|
|
37
38
|
|
38
39
|
# Add the optional parameters and options if not nil
|
39
40
|
params[:password] = config.vm_password unless config.vm_password.nil?
|
40
41
|
params[:location] = config.vm_location unless config.vm_location.nil?
|
41
|
-
params[:affinity_group] = config.vm_affinity_group unless
|
42
|
-
|
43
|
-
|
44
|
-
options[:
|
45
|
-
config.
|
46
|
-
|
47
|
-
config.
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
options[:
|
53
|
-
|
54
|
-
options[:
|
55
|
-
config.
|
56
|
-
options[:
|
57
|
-
config.
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
options[:availability_set_name] = config.availability_set_name unless \
|
65
|
-
config.availability_set_name.nil?
|
66
|
-
options[:virtual_network_name] = config.vm_virtual_network_name unless \
|
67
|
-
config.vm_virtual_network_name.nil?
|
42
|
+
params[:affinity_group] = config.vm_affinity_group unless config.vm_affinity_group.nil?
|
43
|
+
|
44
|
+
options[:storage_account_name] = config.storage_acct_name unless config.storage_acct_name.nil?
|
45
|
+
options[:deployment_name] = config.deployment_name unless config.deployment_name.nil?
|
46
|
+
options[:tcp_endpoints] = config.tcp_endpoints unless config.tcp_endpoints.nil?
|
47
|
+
|
48
|
+
unless config.private_key_file.nil? && env[:machine].config.ssh.private_key_path.nil?
|
49
|
+
options[:private_key_file] = File.expand_path(config.private_key_file || env[:machine].config.ssh.private_key_path.first)
|
50
|
+
end
|
51
|
+
|
52
|
+
options[:ssh_port] = config.ssh_port unless config.ssh_port.nil?
|
53
|
+
options[:vm_size] = config.vm_size unless config.vm_size.nil?
|
54
|
+
options[:winrm_transport] = config.winrm_transport unless config.winrm_transport.nil?
|
55
|
+
options[:winrm_http_port] = config.winrm_http_port unless config.winrm_http_port.nil?
|
56
|
+
options[:winrm_https_port] = config.winrm_https_port unless config.winrm_https_port.nil?
|
57
|
+
options[:availability_set_name] = config.availability_set_name unless config.availability_set_name.nil?
|
58
|
+
options[:virtual_network_name] = config.vm_virtual_network_name unless config.vm_virtual_network_name.nil?
|
59
|
+
|
60
|
+
|
61
|
+
if params[:password] && options[:private_key_file]
|
62
|
+
env[:ui].warn('You specified both a password and a private key file. The password will be used rather than ' +
|
63
|
+
'the private key. If you would like to use asymmetric key auth, do not specify a password.')
|
64
|
+
end
|
68
65
|
|
69
66
|
add_role = false
|
70
67
|
|
@@ -77,8 +74,8 @@ module VagrantPlugins
|
|
77
74
|
if config.cloud_service_name && !config.cloud_service_name.empty?
|
78
75
|
begin
|
79
76
|
cloud_service = ManagementHttpRequest.new(
|
80
|
-
|
81
|
-
|
77
|
+
:get,
|
78
|
+
"/services/hostedservices/#{config.cloud_service_name}?embed-detail=true"
|
82
79
|
).call
|
83
80
|
|
84
81
|
deployments = cloud_service.css 'HostedService Deployments Deployment'
|
data/lib/vagrant-azure/config.rb
CHANGED
@@ -34,10 +34,6 @@ module VagrantPlugins
|
|
34
34
|
alias :ssh_private_key_file :private_key_file
|
35
35
|
alias :ssh_private_key_file= :private_key_file=
|
36
36
|
|
37
|
-
attr_accessor :certificate_file
|
38
|
-
alias :ssh_certificate_file :certificate_file
|
39
|
-
alias :ssh_certificate_file= :certificate_file=
|
40
|
-
|
41
37
|
attr_accessor :ssh_port
|
42
38
|
attr_accessor :vm_size
|
43
39
|
attr_accessor :winrm_transport
|
@@ -66,7 +62,6 @@ module VagrantPlugins
|
|
66
62
|
@deployment_name = UNSET_VALUE
|
67
63
|
@tcp_endpoints = UNSET_VALUE
|
68
64
|
@private_key_file = UNSET_VALUE
|
69
|
-
@certificate_file = UNSET_VALUE
|
70
65
|
@ssh_port = UNSET_VALUE
|
71
66
|
@vm_size = UNSET_VALUE
|
72
67
|
@winrm_transport = UNSET_VALUE
|
@@ -77,22 +72,17 @@ module VagrantPlugins
|
|
77
72
|
end
|
78
73
|
|
79
74
|
def finalize!
|
80
|
-
@storage_acct_name = ENV[
|
81
|
-
|
82
|
-
@
|
83
|
-
|
84
|
-
@
|
85
|
-
@mgmt_certificate == UNSET_VALUE
|
86
|
-
@mgmt_endpoint = ENV["AZURE_MANAGEMENT_ENDPOINT"] if \
|
87
|
-
@mgmt_endpoint == UNSET_VALUE
|
88
|
-
@subscription_id = ENV["AZURE_SUBSCRIPTION_ID"] if \
|
89
|
-
@subscription_id == UNSET_VALUE
|
75
|
+
@storage_acct_name = ENV['AZURE_STORAGE_ACCOUNT'] if @storage_acct_name == UNSET_VALUE
|
76
|
+
@storage_access_key = ENV['AZURE_STORAGE_ACCESS_KEY'] if @storage_access_key == UNSET_VALUE
|
77
|
+
@mgmt_certificate = ENV['AZURE_MANAGEMENT_CERTIFICATE'] if @mgmt_certificate == UNSET_VALUE
|
78
|
+
@mgmt_endpoint = ENV['AZURE_MANAGEMENT_ENDPOINT'] if @mgmt_endpoint == UNSET_VALUE
|
79
|
+
@subscription_id = ENV['AZURE_SUBSCRIPTION_ID'] if @subscription_id == UNSET_VALUE
|
90
80
|
|
91
81
|
@vm_name = nil if @vm_name == UNSET_VALUE
|
92
82
|
@vm_user = 'vagrant' if @vm_user == UNSET_VALUE
|
93
83
|
@vm_password = nil if @vm_password == UNSET_VALUE
|
94
84
|
@vm_image = nil if @vm_image == UNSET_VALUE
|
95
|
-
@vm_location =
|
85
|
+
@vm_location = 'West US' if @vm_location == UNSET_VALUE
|
96
86
|
@vm_affinity_group = nil if @vm_affinity_group == UNSET_VALUE
|
97
87
|
@vm_virtual_network_name = nil if @vm_virtual_network_name == UNSET_VALUE
|
98
88
|
|
@@ -100,7 +90,7 @@ module VagrantPlugins
|
|
100
90
|
@deployment_name = nil if @deployment_name == UNSET_VALUE
|
101
91
|
@tcp_endpoints = nil if @tcp_endpoints == UNSET_VALUE
|
102
92
|
@private_key_file = nil if @private_key_file == UNSET_VALUE
|
103
|
-
|
93
|
+
|
104
94
|
@ssh_port = nil if @ssh_port == UNSET_VALUE
|
105
95
|
@vm_size = nil if @vm_size == UNSET_VALUE
|
106
96
|
@winrm_transport = nil if @winrm_transport == UNSET_VALUE
|
@@ -125,36 +115,40 @@ module VagrantPlugins
|
|
125
115
|
end
|
126
116
|
end
|
127
117
|
|
128
|
-
def merge(other)
|
129
|
-
super.tap do |result|
|
130
|
-
result.mgmt_certificate = other.mgmt_certificate || \
|
131
|
-
self.mgmt_certificate
|
132
|
-
result.mgmt_endpoint = other.mgmt_endpoint || \
|
133
|
-
self.mgmt_endpoint
|
134
|
-
result.subscription_id = other.subscription_id || \
|
135
|
-
self.subscription_id
|
136
|
-
result.storage_acct_name = other.storage_acct_name || \
|
137
|
-
self.storage_acct_name
|
138
|
-
result.storage_access_key = other.storage_access_key || \
|
139
|
-
self.storage_access_key
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
118
|
def validate(machine)
|
144
119
|
errors = _detected_errors
|
145
120
|
|
146
121
|
# Azure connection properties related validation.
|
147
|
-
errors <<
|
148
|
-
|
149
|
-
errors <<
|
150
|
-
@mgmt_certificate.nil?
|
151
|
-
errors << "vagrant_azure.mgmt_endpoint.required" if \
|
152
|
-
@mgmt_endpoint.nil?
|
122
|
+
errors << 'vagrant_azure.subscription_id.required' if @subscription_id.nil?
|
123
|
+
errors << 'vagrant_azure.mgmt_certificate.required' if @mgmt_certificate.nil?
|
124
|
+
errors << 'vagrant_azure.mgmt_endpoint.required' if @mgmt_endpoint.nil?
|
153
125
|
|
154
126
|
# Azure Virtual Machine related validation
|
155
|
-
errors <<
|
127
|
+
errors << 'vagrant_azure.vm_name.required' if @vm_name.nil?
|
128
|
+
|
129
|
+
paths = machine.config.ssh.private_key_path
|
130
|
+
unless @vm_password || machine.config.ssh.password || @private_key_file || (paths && paths.count > 0)
|
131
|
+
errors << 'You must provide one of the following: ssh.private_key_path, azure.private_key_file, ssh.password or azure.vm_password.'
|
132
|
+
end
|
133
|
+
|
134
|
+
if (@private_key_file || (paths && paths.count > 0)) && (@vm_password || machine.config.ssh.password)
|
135
|
+
machine.config.ssh.password = @vm_password = nil
|
136
|
+
machine.ui.warn('You specified both private_key and password. Vagrant-Azure will only use the private_key in this case.')
|
137
|
+
end
|
138
|
+
|
139
|
+
if machine.config.ssh.password.nil? && @vm_password
|
140
|
+
machine.config.ssh.password = @vm_password
|
141
|
+
elsif machine.config.ssh.password && @vm_password.nil?
|
142
|
+
@vm_password = machine.config.ssh.password
|
143
|
+
end
|
144
|
+
|
145
|
+
if machine.config.ssh.private_key_path.nil? && @private_key_file
|
146
|
+
machine.config.ssh.private_key_path = [File.expand_path(@private_key_file)]
|
147
|
+
elsif machine.config.ssh.private_key_path && @private_key_file.nil?
|
148
|
+
@private_key_file = File.expand_path(paths.first)
|
149
|
+
end
|
156
150
|
|
157
|
-
{
|
151
|
+
{ 'Microsoft Azure Provider' => errors }
|
158
152
|
end
|
159
153
|
end
|
160
154
|
end
|
@@ -1,77 +1,12 @@
|
|
1
|
-
# patch no_ssl_peer_validation for ssl based winrm
|
2
|
-
|
3
|
-
WinRM::HTTP::HttpTransport.class_eval do
|
4
|
-
|
5
|
-
# provide a patch for no peer verification.
|
6
|
-
# the patch exists upstream, but vagrant depends on an older version of winrm
|
7
|
-
def no_ssl_peer_verification!
|
8
|
-
@httpcli.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
WinRM::HTTP::HttpSSL.class_eval do
|
13
|
-
|
14
|
-
# provide a constructor that offers the ability to disable peer verification
|
15
|
-
def initialize(endpoint, user, pass, ca_trust_path = nil, opts)
|
16
|
-
super(endpoint)
|
17
|
-
@httpcli.set_auth(endpoint, user, pass)
|
18
|
-
@httpcli.ssl_config.set_trust_ca(ca_trust_path) unless ca_trust_path.nil?
|
19
|
-
no_sspi_auth! if opts[:disable_sspi]
|
20
|
-
basic_auth_only! if opts[:basic_auth_only]
|
21
|
-
no_ssl_peer_verification! if opts[:no_ssl_peer_verification]
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
|
26
1
|
VagrantPlugins::CommunicatorWinRM::WinRMShell.class_eval do
|
27
|
-
EXCEPTIONS = class_variable_get(:@@exceptions_to_retry_on)
|
28
|
-
|
29
|
-
protected
|
30
|
-
|
31
|
-
# patch the timeout being raised from openssl that is not handled properly
|
32
|
-
def execute_shell_with_retry(command, shell, &block)
|
33
|
-
retryable(:tries => @max_tries, :on => EXCEPTIONS, :sleep => 10) do
|
34
|
-
@logger.debug("#{shell} executing:\n#{command}")
|
35
|
-
begin
|
36
|
-
output = session.send(shell, command) do |out, err|
|
37
|
-
block.call(:stdout, out) if block_given? && out
|
38
|
-
block.call(:stderr, err) if block_given? && err
|
39
|
-
end
|
40
|
-
rescue Exception => ex
|
41
|
-
raise Timeout::Error if ex.message =~ /execution expired/ # received not friendly timeout, raise a more friendly error
|
42
|
-
raise # didn't include execution expired, so raise for retryable to handle
|
43
|
-
end
|
44
|
-
@logger.debug("Output: #{output.inspect}")
|
45
|
-
return output
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
# create a new session using ssl rather than kerberos or plaintext
|
50
|
-
def new_session
|
51
|
-
@logger.info("Attempting to connect to WinRM (patched)...")
|
52
|
-
@logger.info(" - Host: #{@host}")
|
53
|
-
@logger.info(" - Port: #{@port}")
|
54
|
-
@logger.info(" - Username: #{@username}")
|
55
|
-
|
56
|
-
client = ::WinRM::WinRMWebService.new(endpoint, :ssl, endpoint_options)
|
57
|
-
client.set_timeout(@timeout_in_seconds)
|
58
|
-
client.toggle_nori_type_casting(:off) #we don't want coersion of types
|
59
|
-
client
|
60
|
-
end
|
61
|
-
|
62
|
-
# override the internal http endpoint
|
63
|
-
def endpoint
|
64
|
-
"https://#{@host}:#{@port}/wsman"
|
65
|
-
end
|
66
|
-
|
67
|
-
# don't verify azure self signed certs and don't try to use sspi
|
68
2
|
def endpoint_options
|
69
3
|
{user: @username,
|
70
4
|
pass: @password,
|
71
5
|
host: @host,
|
72
6
|
port: @port,
|
73
|
-
|
74
|
-
no_ssl_peer_verification:
|
75
|
-
disable_sspi: true
|
7
|
+
basic_auth_only: false,
|
8
|
+
no_ssl_peer_verification: !@config.ssl_peer_verification,
|
9
|
+
disable_sspi: true
|
10
|
+
}
|
76
11
|
end
|
77
12
|
end
|
data/lib/vagrant-azure/plugin.rb
CHANGED
@@ -58,8 +58,6 @@ module VagrantPlugins
|
|
58
58
|
def self.apply_patches
|
59
59
|
lib_path = Pathname.new(File.expand_path('../../vagrant-azure', __FILE__))
|
60
60
|
Vagrant.plugin('2').manager.communicators[:winrm]
|
61
|
-
require 'kconv'
|
62
|
-
require lib_path.join('monkey_patch/azure')
|
63
61
|
require lib_path.join('monkey_patch/winrm')
|
64
62
|
end
|
65
63
|
|
data/vagrant-azure.gemspec
CHANGED
@@ -4,56 +4,24 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'vagrant-azure/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
|
-
s.name =
|
7
|
+
s.name = 'vagrant-azure'
|
8
8
|
s.version = VagrantPlugins::WinAzure::VERSION
|
9
|
-
s.authors =
|
10
|
-
s.description =
|
11
|
-
s.summary =
|
12
|
-
s.homepage =
|
13
|
-
s.license =
|
14
|
-
|
15
|
-
s.
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
gitignore.map! { |line| line.chomp.strip }
|
28
|
-
gitignore.reject! { |line| line.empty? || line =~ /^(#|!)/ }
|
29
|
-
|
30
|
-
unignored_files = all_files.reject do |file|
|
31
|
-
# Ignore any directories, the gemspec only cares about files
|
32
|
-
next true if File.directory?(file)
|
33
|
-
|
34
|
-
# Ignore any paths that match anything in the gitignore. We do
|
35
|
-
# two tests here:
|
36
|
-
#
|
37
|
-
# - First, test to see if the entire path matches the gitignore.
|
38
|
-
# - Second, match if the basename does, this makes it so that things
|
39
|
-
# like '.DS_Store' will match sub-directories too (same behavior
|
40
|
-
# as git).
|
41
|
-
#
|
42
|
-
gitignore.any? do |ignore|
|
43
|
-
File.fnmatch(ignore, file, File::FNM_PATHNAME) ||
|
44
|
-
File.fnmatch(ignore, File.basename(file), File::FNM_PATHNAME)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
s.files = unignored_files
|
49
|
-
s.executables = unignored_files.map { |f| f[/^bin\/(.*)/, 1] }.compact
|
50
|
-
|
51
|
-
s.add_runtime_dependency "azure", "0.6.4"
|
52
|
-
s.add_runtime_dependency "httpclient", "2.4.0"
|
53
|
-
|
54
|
-
s.add_development_dependency "bundler", "~> 1.3"
|
55
|
-
s.add_development_dependency "rake"
|
56
|
-
s.add_development_dependency "minitest"
|
57
|
-
s.add_development_dependency "minitest-reporters"
|
58
|
-
s.add_development_dependency "mocha"
|
9
|
+
s.authors = %w(MSOpenTech Azure)
|
10
|
+
s.description = 'Enable Vagrant to manage machines in Azure.'
|
11
|
+
s.summary = 'Enable Vagrant to manage Windows and Linux machines in Azure.'
|
12
|
+
s.homepage = 'https://github.com/MSOpenTech/vagrant-azure'
|
13
|
+
s.license = 'Apache 2.0'
|
14
|
+
s.require_paths = ['lib']
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.bindir = 'bin'
|
17
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
|
19
|
+
s.add_runtime_dependency 'azure', '0.7.0'
|
20
|
+
s.add_runtime_dependency 'httpclient', '2.4.0'
|
21
|
+
|
22
|
+
s.add_development_dependency 'bundler', '~> 1.3'
|
23
|
+
s.add_development_dependency 'rake'
|
24
|
+
s.add_development_dependency 'minitest'
|
25
|
+
s.add_development_dependency 'minitest-reporters'
|
26
|
+
s.add_development_dependency 'mocha'
|
59
27
|
end
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-azure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- MSOpenTech
|
8
|
+
- Azure
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2015-
|
12
|
+
date: 2015-08-17 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: azure
|
@@ -16,14 +17,14 @@ dependencies:
|
|
16
17
|
requirements:
|
17
18
|
- - '='
|
18
19
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
20
|
+
version: 0.7.0
|
20
21
|
type: :runtime
|
21
22
|
prerelease: false
|
22
23
|
version_requirements: !ruby/object:Gem::Requirement
|
23
24
|
requirements:
|
24
25
|
- - '='
|
25
26
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
27
|
+
version: 0.7.0
|
27
28
|
- !ruby/object:Gem::Dependency
|
28
29
|
name: httpclient
|
29
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,7 +109,7 @@ dependencies:
|
|
108
109
|
- - ">="
|
109
110
|
- !ruby/object:Gem::Version
|
110
111
|
version: '0'
|
111
|
-
description: Enable Vagrant to manage machines in Azure
|
112
|
+
description: Enable Vagrant to manage machines in Azure.
|
112
113
|
email:
|
113
114
|
executables: []
|
114
115
|
extensions: []
|
@@ -122,13 +123,13 @@ files:
|
|
122
123
|
- Rakefile
|
123
124
|
- dummy.box
|
124
125
|
- example_box/README.md
|
126
|
+
- example_box/Vagrantfile
|
125
127
|
- example_box/metadata.json
|
126
128
|
- lib/vagrant-azure.rb
|
127
129
|
- lib/vagrant-azure/action.rb
|
128
130
|
- lib/vagrant-azure/action/connect_azure.rb
|
129
131
|
- lib/vagrant-azure/action/os_type.rb
|
130
132
|
- lib/vagrant-azure/action/powershell_run.rb
|
131
|
-
- lib/vagrant-azure/action/provision.rb
|
132
133
|
- lib/vagrant-azure/action/rdp.rb
|
133
134
|
- lib/vagrant-azure/action/read_ssh_info.rb
|
134
135
|
- lib/vagrant-azure/action/read_state.rb
|
@@ -140,7 +141,6 @@ files:
|
|
140
141
|
- lib/vagrant-azure/action/sync_folders.rb
|
141
142
|
- lib/vagrant-azure/action/terminate_instance.rb
|
142
143
|
- lib/vagrant-azure/action/vagrant_azure_service.rb
|
143
|
-
- lib/vagrant-azure/action/wait_for_communicate.rb
|
144
144
|
- lib/vagrant-azure/action/wait_for_state.rb
|
145
145
|
- lib/vagrant-azure/capabilities/winrm.rb
|
146
146
|
- lib/vagrant-azure/command/powershell.rb
|
@@ -148,12 +148,9 @@ files:
|
|
148
148
|
- lib/vagrant-azure/config.rb
|
149
149
|
- lib/vagrant-azure/driver.rb
|
150
150
|
- lib/vagrant-azure/errors.rb
|
151
|
-
- lib/vagrant-azure/monkey_patch/azure.rb
|
152
151
|
- lib/vagrant-azure/monkey_patch/winrm.rb
|
153
152
|
- lib/vagrant-azure/plugin.rb
|
154
153
|
- lib/vagrant-azure/provider.rb
|
155
|
-
- lib/vagrant-azure/provisioner/chef-solo.rb
|
156
|
-
- lib/vagrant-azure/provisioner/puppet.rb
|
157
154
|
- lib/vagrant-azure/version.rb
|
158
155
|
- locales/en.yml
|
159
156
|
- templates/provisioners/chef-solo/solo.erb
|
@@ -178,9 +175,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
178
175
|
version: '0'
|
179
176
|
requirements: []
|
180
177
|
rubyforge_project:
|
181
|
-
rubygems_version: 2.
|
178
|
+
rubygems_version: 2.4.6
|
182
179
|
signing_key:
|
183
180
|
specification_version: 4
|
184
|
-
summary: Enable Vagrant to manage machines in Azure
|
181
|
+
summary: Enable Vagrant to manage Windows and Linux machines in Azure.
|
185
182
|
test_files: []
|
186
|
-
has_rdoc:
|
@@ -1,42 +0,0 @@
|
|
1
|
-
#---------------------------------------------------------------------------
|
2
|
-
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
-
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
4
|
-
# See License.txt in the project root for license information.
|
5
|
-
#---------------------------------------------------------------------------
|
6
|
-
|
7
|
-
module VagrantPlugins
|
8
|
-
module WinAzure
|
9
|
-
module Action
|
10
|
-
class Provision < Vagrant::Action::Builtin::Provision
|
11
|
-
# Override the core vagrant method and branch out for windows
|
12
|
-
def run_provisioner(env)
|
13
|
-
env[:machine].id =~ /@/
|
14
|
-
vm = env[:azure_vm_service].get_virtual_machine($`, $')
|
15
|
-
env[:ui].info "VM OS: #{vm.os_type.to_sym}"
|
16
|
-
|
17
|
-
if vm.os_type.to_sym == :Windows
|
18
|
-
env[:ui].info 'Provisioning for Windows'
|
19
|
-
|
20
|
-
case env[:provisioner].class.to_s
|
21
|
-
when 'VagrantPlugins::Shell::Provisioner'
|
22
|
-
env[:provisioner].provision
|
23
|
-
when 'VagrantPlugins::Puppet::Provisioner::Puppet'
|
24
|
-
VagrantPlugins::WinAzure::Provisioner::Puppet.new(
|
25
|
-
env
|
26
|
-
).provision_for_windows
|
27
|
-
when 'VagrantPlugins::Chef::Provisioner::ChefSolo'
|
28
|
-
VagrantPlugins::WinAzure::Provisioner::ChefSolo.new(
|
29
|
-
env
|
30
|
-
).provision_for_windows
|
31
|
-
else
|
32
|
-
env[:provisioner].provision
|
33
|
-
end
|
34
|
-
else
|
35
|
-
env[:ui].info 'Provisioning using SSH'
|
36
|
-
env[:provisioner].provision
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
#--------------------------------------------------------------------------
|
2
|
-
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
-
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
4
|
-
# See License.txt in the project root for license information.
|
5
|
-
#--------------------------------------------------------------------------
|
6
|
-
require 'log4r'
|
7
|
-
require 'timeout'
|
8
|
-
|
9
|
-
module VagrantPlugins
|
10
|
-
module WinAzure
|
11
|
-
module Action
|
12
|
-
class WaitForCommunicate
|
13
|
-
def initialize(app, env)
|
14
|
-
@app = app
|
15
|
-
@logger = Log4r::Logger.new('vagrant_azure::action::wait_for_communicate')
|
16
|
-
end
|
17
|
-
|
18
|
-
def call(env)
|
19
|
-
|
20
|
-
if !env[:interrupted]
|
21
|
-
# Wait for SSH to be ready.
|
22
|
-
env[:ui].info(I18n.t('vagrant_azure.waiting_for_comm'))
|
23
|
-
while true
|
24
|
-
# If we're interrupted then just back out
|
25
|
-
break if env[:interrupted]
|
26
|
-
break if env[:machine].communicate.ready?
|
27
|
-
sleep 5
|
28
|
-
end
|
29
|
-
|
30
|
-
# Ready and booted!
|
31
|
-
env[:ui].info(I18n.t('vagrant_azure.comm_ready'))
|
32
|
-
end
|
33
|
-
|
34
|
-
@app.call(env)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'azure'
|
3
|
-
|
4
|
-
# Patch azure-ruby-sdk to enable vhds to be created every millisecond as opposed to every minute...
|
5
|
-
Azure::VirtualMachineManagement::Serialization.module_eval do
|
6
|
-
def self.role_to_xml(params, options)
|
7
|
-
builder = Nokogiri::XML::Builder.new do |xml|
|
8
|
-
xml.PersistentVMRole(
|
9
|
-
'xmlns' => 'http://schemas.microsoft.com/windowsazure',
|
10
|
-
'xmlns:i' => 'http://www.w3.org/2001/XMLSchema-instance'
|
11
|
-
) do
|
12
|
-
xml.RoleName { xml.text params[:vm_name] }
|
13
|
-
xml.OsVersion('i:nil' => 'true')
|
14
|
-
xml.RoleType 'PersistentVMRole'
|
15
|
-
|
16
|
-
xml.ConfigurationSets do
|
17
|
-
provisioning_configuration_to_xml(xml, params, options)
|
18
|
-
xml.ConfigurationSet('i:type' => 'NetworkConfigurationSet') do
|
19
|
-
xml.ConfigurationSetType 'NetworkConfiguration'
|
20
|
-
xml.InputEndpoints do
|
21
|
-
default_endpoints_to_xml(xml, options)
|
22
|
-
tcp_endpoints_to_xml(
|
23
|
-
xml,
|
24
|
-
options[:tcp_endpoints],
|
25
|
-
options[:existing_ports]
|
26
|
-
) if options[:tcp_endpoints]
|
27
|
-
end
|
28
|
-
if options[:virtual_network_name] && options[:subnet_name]
|
29
|
-
xml.SubnetNames do
|
30
|
-
xml.SubnetName options[:subnet_name]
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
xml.AvailabilitySetName options[:availability_set_name]
|
36
|
-
xml.Label Base64.encode64(params[:vm_name]).strip
|
37
|
-
xml.OSVirtualHardDisk do
|
38
|
-
xml.MediaLink 'http://' + options[:storage_account_name] + '.blob.core.windows.net/vhds/' + (Time.now.strftime('disk_%Y_%m_%d_%H_%M_%S_%L')) + '.vhd'
|
39
|
-
xml.SourceImageName params[:image]
|
40
|
-
end
|
41
|
-
xml.RoleSize options[:vm_size]
|
42
|
-
end
|
43
|
-
end
|
44
|
-
builder.doc
|
45
|
-
end
|
46
|
-
end
|
@@ -1,178 +0,0 @@
|
|
1
|
-
#-------------------------------------------------------------------------
|
2
|
-
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
-
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
4
|
-
# See License.txt in the project root for license information.
|
5
|
-
#--------------------------------------------------------------------------
|
6
|
-
|
7
|
-
require "fileutils"
|
8
|
-
require "tempfile"
|
9
|
-
|
10
|
-
module VagrantPlugins
|
11
|
-
module WinAzure
|
12
|
-
module Provisioner
|
13
|
-
class ChefSolo
|
14
|
-
attr_reader :provisioner
|
15
|
-
|
16
|
-
def initialize(env)
|
17
|
-
@env = env
|
18
|
-
@provisioner = env[:provisioner]
|
19
|
-
end
|
20
|
-
|
21
|
-
def provision_for_windows
|
22
|
-
# Copy the chef cookbooks roles data bags and environment folders to Guest
|
23
|
-
copy_folder_to_guest(provisioner.cookbook_folders)
|
24
|
-
copy_folder_to_guest(provisioner.role_folders)
|
25
|
-
copy_folder_to_guest(provisioner.data_bags_folders)
|
26
|
-
copy_folder_to_guest(provisioner.environments_folders)
|
27
|
-
|
28
|
-
# Upload Encrypted data bag
|
29
|
-
upload_encrypted_data_bag_secret if config.encrypted_data_bag_secret_key_path
|
30
|
-
setup_json
|
31
|
-
setup_solo_config
|
32
|
-
run_chef_solo
|
33
|
-
|
34
|
-
# TODO
|
35
|
-
# delete_encrypted_data_bag_secret
|
36
|
-
end
|
37
|
-
|
38
|
-
def setup_json
|
39
|
-
@env[:machine].env.ui.info I18n.t("vagrant.provisioners.chef.json")
|
40
|
-
|
41
|
-
# Get the JSON that we're going to expose to Chef
|
42
|
-
json = config.json
|
43
|
-
json[:run_list] = config.run_list if !config.run_list.empty?
|
44
|
-
json = JSON.pretty_generate(json)
|
45
|
-
|
46
|
-
# Create a temporary file to store the data so we
|
47
|
-
# can upload it
|
48
|
-
temp = Tempfile.new("vagrant")
|
49
|
-
temp.write(json)
|
50
|
-
temp.close
|
51
|
-
|
52
|
-
remote_file = File.join(config.provisioning_path, "dna.json")
|
53
|
-
@env[:machine].provider.driver.upload(temp.path, remote_file)
|
54
|
-
end
|
55
|
-
|
56
|
-
def setup_solo_config
|
57
|
-
cookbooks_path = guest_paths(provisioner.cookbook_folders)
|
58
|
-
roles_path = guest_paths(provisioner.role_folders)
|
59
|
-
data_bags_path = guest_paths(provisioner.data_bags_folders).first
|
60
|
-
environments_path = guest_paths(provisioner.environments_folders).first
|
61
|
-
source_path = "#{VagrantPlugins::WinAzure.source_root}"
|
62
|
-
template_path = source_path + "/templates/provisioners/chef-solo/solo"
|
63
|
-
setup_config(template_path, "solo.rb", {
|
64
|
-
:cookbooks_path => cookbooks_path,
|
65
|
-
:recipe_url => config.recipe_url,
|
66
|
-
:roles_path => roles_path,
|
67
|
-
:data_bags_path => data_bags_path,
|
68
|
-
:environments_path => environments_path
|
69
|
-
})
|
70
|
-
end
|
71
|
-
|
72
|
-
def setup_config(template, filename, template_vars)
|
73
|
-
# If we have custom configuration, upload it
|
74
|
-
remote_custom_config_path = nil
|
75
|
-
if config.custom_config_path
|
76
|
-
expanded = File.expand_path(
|
77
|
-
config.custom_config_path, @machine.env.root_path)
|
78
|
-
remote_custom_config_path = File.join(
|
79
|
-
config.provisioning_path, "custom-config.rb")
|
80
|
-
|
81
|
-
@env[:machine].provider.driver.upload(expanded, remote_custom_config_path)
|
82
|
-
end
|
83
|
-
|
84
|
-
config_file = Vagrant::Util::TemplateRenderer.render(template, {
|
85
|
-
:custom_configuration => remote_custom_config_path,
|
86
|
-
:file_cache_path => config.file_cache_path,
|
87
|
-
:file_backup_path => config.file_backup_path,
|
88
|
-
:log_level => config.log_level.to_sym,
|
89
|
-
:verbose_logging => config.verbose_logging,
|
90
|
-
:http_proxy => config.http_proxy,
|
91
|
-
:http_proxy_user => config.http_proxy_user,
|
92
|
-
:http_proxy_pass => config.http_proxy_pass,
|
93
|
-
:https_proxy => config.https_proxy,
|
94
|
-
:https_proxy_user => config.https_proxy_user,
|
95
|
-
:https_proxy_pass => config.https_proxy_pass,
|
96
|
-
:no_proxy => config.no_proxy,
|
97
|
-
:formatter => config.formatter
|
98
|
-
}.merge(template_vars))
|
99
|
-
|
100
|
-
# Create a temporary file to store the data so we can upload it
|
101
|
-
temp = Tempfile.new("vagrant")
|
102
|
-
temp.write(config_file)
|
103
|
-
temp.close
|
104
|
-
|
105
|
-
remote_file = File.join(config.provisioning_path, filename)
|
106
|
-
@env[:machine].provider.driver.upload(temp.path, remote_file)
|
107
|
-
end
|
108
|
-
|
109
|
-
def run_chef_solo
|
110
|
-
if config.run_list && config.run_list.empty?
|
111
|
-
@env[:machine].ui.warn(I18n.t("vagrant.chef_run_list_empty"))
|
112
|
-
end
|
113
|
-
|
114
|
-
options = [
|
115
|
-
"-c #{config.provisioning_path}/solo.rb",
|
116
|
-
"-j #{config.provisioning_path}/dna.json"
|
117
|
-
]
|
118
|
-
|
119
|
-
command_env = config.binary_env ? "#{config.binary_env} " : ""
|
120
|
-
command_args = config.arguments ? " #{config.arguments}" : ""
|
121
|
-
command = "#{command_env}#{chef_binary_path("chef-solo")} " +
|
122
|
-
"#{options.join(" ")} #{command_args}"
|
123
|
-
config.attempts.times do |attempt|
|
124
|
-
if attempt == 0
|
125
|
-
@env[:machine].env.ui.info I18n.t("vagrant.provisioners.chef.running_solo")
|
126
|
-
else
|
127
|
-
@env[:machine].env.ui.info I18n.t("vagrant.provisioners.chef.running_solo_again")
|
128
|
-
end
|
129
|
-
|
130
|
-
command
|
131
|
-
|
132
|
-
@env[:machine].provider.driver.run_remote_ps(command) do |type, data|
|
133
|
-
# Output the data with the proper color based on the stream.
|
134
|
-
if (type == :stdout || type == :stderr)
|
135
|
-
@env[:ui].detail data
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
end
|
141
|
-
|
142
|
-
def upload_encrypted_data_bag_secret
|
143
|
-
@machine.env.ui.info I18n.t("vagrant.provisioners.chef.upload_encrypted_data_bag_secret_key")
|
144
|
-
@env[:machine].provider.driver.upload(encrypted_data_bag_secret_key_path,
|
145
|
-
config.encrypted_data_bag_secret)
|
146
|
-
end
|
147
|
-
|
148
|
-
def encrypted_data_bag_secret_key_path
|
149
|
-
File.expand_path(config.encrypted_data_bag_secret_key_path, @env[:machine].env.root_path)
|
150
|
-
end
|
151
|
-
|
152
|
-
def config
|
153
|
-
provisioner.config
|
154
|
-
end
|
155
|
-
|
156
|
-
def guest_paths(folders)
|
157
|
-
folders.map { |parts| parts[2] }
|
158
|
-
end
|
159
|
-
|
160
|
-
# Returns the path to the Chef binary, taking into account the
|
161
|
-
# `binary_path` configuration option.
|
162
|
-
def chef_binary_path(binary)
|
163
|
-
return binary if !config.binary_path
|
164
|
-
return File.join(config.binary_path, binary)
|
165
|
-
end
|
166
|
-
|
167
|
-
def copy_folder_to_guest(folders)
|
168
|
-
folders.each do |type, local_path, remote_path|
|
169
|
-
if type == :host
|
170
|
-
@env[:machine].provider.driver.upload(local_path, remote_path)
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
@@ -1,116 +0,0 @@
|
|
1
|
-
#---------------------------------------------------------------------------
|
2
|
-
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
-
# All Rights Reserved. Licensed under the Apache License, Version 2.0.
|
4
|
-
# See License.txt in the project root for license information.
|
5
|
-
#---------------------------------------------------------------------------
|
6
|
-
require 'fileutils'
|
7
|
-
require 'tempfile'
|
8
|
-
|
9
|
-
module VagrantPlugins
|
10
|
-
module WinAzure
|
11
|
-
module Provisioner
|
12
|
-
class Puppet
|
13
|
-
attr_reader :provisioner
|
14
|
-
|
15
|
-
def initialize(env)
|
16
|
-
@env = env
|
17
|
-
@provisioner = env[:provisioner]
|
18
|
-
end
|
19
|
-
|
20
|
-
def provision_for_windows
|
21
|
-
options = [config.options].flatten
|
22
|
-
@module_paths = provisioner.instance_variable_get('@module_paths')
|
23
|
-
@hiera_config_path = provisioner.instance_variable_get(
|
24
|
-
'@hiera_config_path'
|
25
|
-
)
|
26
|
-
@manifest_file = provisioner.instance_variable_get('@manifest_file')
|
27
|
-
|
28
|
-
# Copy the manifests directory to the guest
|
29
|
-
if config.manifests_path[0].to_sym == :host
|
30
|
-
@env[:machine].provider.driver.upload(
|
31
|
-
File.expand_path(
|
32
|
-
config.manifests_path[1], @env[:machine].env.root_path
|
33
|
-
),
|
34
|
-
provisioner.manifests_guest_path
|
35
|
-
)
|
36
|
-
end
|
37
|
-
|
38
|
-
# Copy the module paths to the guest
|
39
|
-
@module_paths.each do |from, to|
|
40
|
-
@env[:machine].provider.driver.upload(from.to_s, to)
|
41
|
-
end
|
42
|
-
|
43
|
-
module_paths = @module_paths.map { |_, to| to }
|
44
|
-
unless module_paths.empty?
|
45
|
-
win_paths = []
|
46
|
-
# Prepend the default module path
|
47
|
-
module_paths.unshift('/ProgramData/PuppetLabs/puppet/etc/modules')
|
48
|
-
module_paths.each do |path|
|
49
|
-
path = path.gsub('/', '\\')
|
50
|
-
path = "C:#{path}" if path =~/^\\/
|
51
|
-
win_paths << path
|
52
|
-
end
|
53
|
-
|
54
|
-
# Add the command line switch to add the module path
|
55
|
-
options << "--modulepath \"#{win_paths.join(';')}\""
|
56
|
-
end
|
57
|
-
|
58
|
-
if @hiera_config_path
|
59
|
-
options << "--hiera_config=#{@hiera_config_path}"
|
60
|
-
|
61
|
-
# Upload Hiera configuration if we have it
|
62
|
-
local_hiera_path = File.expand_path(
|
63
|
-
config.hiera_config_path,
|
64
|
-
@env[:machine].env.root_path
|
65
|
-
)
|
66
|
-
|
67
|
-
@env[:machine].provider.driver.upload(
|
68
|
-
local_hiera_path,
|
69
|
-
@hiera_config_path
|
70
|
-
)
|
71
|
-
end
|
72
|
-
|
73
|
-
options << "--manifestdir #{provisioner.manifests_guest_path}"
|
74
|
-
options << "--detailed-exitcodes"
|
75
|
-
options << @manifest_file
|
76
|
-
options = options.join(' ')
|
77
|
-
|
78
|
-
# Build up the custome facts if we have any
|
79
|
-
facter = ''
|
80
|
-
unless config.facter.empty?
|
81
|
-
facts = []
|
82
|
-
config.facter.each do |key, value|
|
83
|
-
facts << "FACTER_#{key}='#{value}'"
|
84
|
-
end
|
85
|
-
|
86
|
-
facter = "#{facts.join(' ')}"
|
87
|
-
end
|
88
|
-
|
89
|
-
command = "#{facter}puppet apply #{options}"
|
90
|
-
|
91
|
-
if config.working_directory
|
92
|
-
command = "cd #{config.working_directory} && #{command}"
|
93
|
-
end
|
94
|
-
|
95
|
-
@env[:ui].info I18n.t(
|
96
|
-
'vagrant.provisioners.puppet.running_puppet',
|
97
|
-
manifest: config.manifest_file
|
98
|
-
)
|
99
|
-
@env[:ui].info 'Executing puppet script in Windows Azure VM'
|
100
|
-
@env[:machine].provider.driver.run_remote_ps(command) do |type, data|
|
101
|
-
# Output the data with the proper color based on the stream.
|
102
|
-
if (type == :stdout || type == :stderr)
|
103
|
-
@env[:ui].detail data
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
protected
|
109
|
-
|
110
|
-
def config
|
111
|
-
provisioner.config
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|