vagrant-azure 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
![Gem Version](https://badge.fury.io/rb/vagrant-azure.png)
|
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
|