vagrant-azure 2.0.0.pre1 → 2.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f5597d47adf91f7395f8b3bec4ab45ca51218f47
4
- data.tar.gz: cb149fbf31e95c1657581e0e213e31bf65c2a63f
3
+ metadata.gz: 5bec96dd4b99f7a5bf92f5d5b8056b1ce4885d44
4
+ data.tar.gz: aa65b0f1615ae25b591ffd59efd462332ea4de93
5
5
  SHA512:
6
- metadata.gz: 1429363e9a70658d9960c7ba9689e8be3fea33ae6a5d4d21731c31d84af5f8d278f7617be87ebab4cd40ec1502a7db32d120dc9b40de32fd766d92bd30376d1b
7
- data.tar.gz: 7d32bd43eed9cedd13938d10f4fe0665330cf03b3698cadbda007c9e0e615f9953d3a1e15bb67b7250f51baa53aae464b4f8a6c3939a01b174e9983e2bd922ab
6
+ metadata.gz: 5f838e34d66d8795e0b0dc00ad4f2529ad230f996e06923ba37adb4e1d16403c263dfca156d292ccc204c5e63ec39fe63491474f8164e8e0efbfc515a90457e2
7
+ data.tar.gz: 3e057b8906ad18b76e15dcf5f8a674bbaa3b050880de1e5e4a188a1efa07c0d811fee2b4e2c855764862bf1b2a8fc151372d4d6709ce252f1eb7f01ac1defe21
data/Gemfile CHANGED
@@ -10,10 +10,10 @@ group :development do
10
10
  # We depend on Vagrant for development, but we don't add it as a
11
11
  # gem dependency because we expect to be installed within the
12
12
  # Vagrant environment itself using `vagrant plugin`.
13
- gem 'vagrant', git: 'git://github.com/mitchellh/vagrant.git', tag: 'v1.7.4'
14
- gem 'dotenv'
13
+ gem 'vagrant', git: 'https://github.com/mitchellh/vagrant.git'
14
+ gem 'bundler', '~>1.10.5'
15
15
  end
16
16
 
17
17
  group :plugins do
18
18
  gem 'vagrant-azure', path: '.'
19
- end
19
+ end
data/README.md CHANGED
@@ -7,14 +7,14 @@ provider to Vagrant, allowing Vagrant to control and provision machines in Micro
7
7
 
8
8
  ## Usage
9
9
 
10
- Install Vagrant 1.7.3 or higher - [Download Vagrant](http://www.vagrantup.com/downloads.html)
10
+ [Download Vagrant](http://www.vagrantup.com/downloads.html)
11
11
 
12
12
  Install the vagrant-azure plugin using the standard Vagrant 1.1+ installation methods. After installing the plugin, you can ```vagrant up``` and use ```azure``` provider. For example:
13
13
 
14
14
  ```
15
- C:\> vagrant plugin install vagrant-azure 2.0.0.pre1
15
+ vagrant plugin install vagrant-azure --plugin-version '2.0.0.pre1' --plugin-prerelease
16
16
  ...
17
- C:\> vagrant up --provider=azure
17
+ vagrant up --provider=azure
18
18
  ...
19
19
  ```
20
20
 
@@ -25,7 +25,7 @@ You'll need an ```azure``` box before you can do ```vagrant up``` though.
25
25
  You can use the dummy box and specify all the required details manually in the ```config.vm.provider``` block in your ```Vagrantfile```. Add the dummy box with the name you want:
26
26
 
27
27
  ```
28
- C:\> vagrant box add azure https://github.com/azure/vagrant-azure/raw/v2.0/dummy.box
28
+ vagrant box add azure https://github.com/azure/vagrant-azure/raw/v2.0/dummy.box
29
29
  ...
30
30
  ```
31
31
 
@@ -55,7 +55,7 @@ end
55
55
  Now you can run
56
56
 
57
57
  ```
58
- C:\> vagrant up --provider=azure
58
+ vagrant up --provider=azure
59
59
  ```
60
60
 
61
61
  This will bring up an Azure VM as per the configuration options set above.
@@ -87,8 +87,8 @@ For instructions on how to setup an Azure Active Directory Application see: http
87
87
  * `location`: (Optional) Azure location to build the VM -- defaults to 'westus'
88
88
  * `vm_name`: (Optional) Name of the virtual machine
89
89
  * `vm_password`: (Optional for *nix) Password for the VM -- This is not recommended for *nix deployments
90
- * `vm_size`: (Optional) VM size to be used -- defaults to 'Standard_D1'. See: https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-linux-sizes/
91
- * `vm_image_urn`: (Optional) Name of the virtual machine image urn to use -- defaults to 'canonical:ubuntuserver:16.04.0-DAILY-LTS:latest'. See: https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-linux-cli-ps-findimage/
90
+ * `vm_size`: (Optional) VM size to be used -- defaults to 'Standard_DS2_v2'. See: https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-linux-sizes/
91
+ * `vm_image_urn`: (Optional) Name of the virtual machine image urn to use -- defaults to 'canonical:ubuntuserver:16.04-LTS:latest'. See: https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-linux-cli-ps-findimage/
92
92
  * `virtual_network_name`: (Optional) Name of the virtual network resource
93
93
  * `subnet_name`: (Optional) Name of the virtual network subnet resource
94
94
  * `instance_ready_timeout`: (Optional) The timeout to wait for an instance to become ready -- default 120 seconds.
data/Rakefile CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  require 'rubygems'
6
6
  require 'bundler/setup'
7
+ require 'rspec/core/rake_task'
7
8
 
8
9
  $stdout.sync = true
9
10
  $stderr.sync = true
@@ -11,3 +12,10 @@ $stderr.sync = true
11
12
  Dir.chdir(File.expand_path('../', __FILE__))
12
13
 
13
14
  Bundler::GemHelper.install_tasks
15
+
16
+ # Install the `spec` task so that we can run tests.
17
+ RSpec::Core::RakeTask.new(:spec) do |t|
18
+ t.rspec_opts = '--order defined'
19
+ end
20
+ # Default task is to run the unit tests
21
+ task :default => :spec
data/dummy.box CHANGED
Binary file
@@ -75,6 +75,16 @@ module VagrantPlugins
75
75
  end
76
76
  end
77
77
 
78
+ # This action is called to read the WinRM info of the machine. The
79
+ # resulting state is expected to be put into the `:machine_winrm_info` key.
80
+ def self.action_read_winrm_info
81
+ Vagrant::Action::Builder.new.tap do |b|
82
+ b.use ConfigValidate
83
+ b.use ConnectAzure
84
+ b.use ReadWinrmInfo
85
+ end
86
+ end
87
+
78
88
  # This action is called to read the state of the machine. The
79
89
  # resulting state is expected to be put into the `:machine_state_id`
80
90
  # key.
@@ -178,6 +188,7 @@ module VagrantPlugins
178
188
  autoload :MessageNotCreated, action_root.join('message_not_created')
179
189
  autoload :MessageWillNotDestroy, action_root.join('message_will_not_destroy')
180
190
  autoload :ReadSSHInfo, action_root.join('read_ssh_info')
191
+ autoload :ReadWinrmInfo, action_root.join('read_winrm_info')
181
192
  autoload :ReadState, action_root.join('read_state')
182
193
  autoload :RestartVM, action_root.join('restart_vm')
183
194
  autoload :RunInstance, action_root.join('run_instance')
@@ -24,9 +24,9 @@ module VagrantPlugins
24
24
  def read_ssh_info(azure, env)
25
25
  return nil if env[:machine].id.nil?
26
26
  parsed = parse_machine_id(env[:machine].id)
27
- public_ip = azure.network.public_ipaddresses.get(parsed[:group], "#{parsed[:name]}-vagrantPublicIP").value!.body
27
+ public_ip = azure.network.public_ipaddresses.get(parsed[:group], "#{parsed[:name]}-vagrantPublicIP")
28
28
 
29
- {:host => public_ip.properties.dns_settings.fqdn, :port => 22}
29
+ {:host => public_ip.dns_settings.fqdn, :port => 22}
30
30
  end
31
31
  end
32
32
  end
@@ -29,9 +29,9 @@ module VagrantPlugins
29
29
  parsed = parse_machine_id(machine.id)
30
30
  vm = nil
31
31
  begin
32
- vm = azure.compute.virtual_machines.get(parsed[:group], parsed[:name], 'instanceView').value!.body
32
+ vm = azure.compute.virtual_machines.get(parsed[:group], parsed[:name], 'instanceView')
33
33
  rescue MsRestAzure::AzureOperationError => ex
34
- if vm.nil? || tearing_down?(vm.properties.instance_view.statuses)
34
+ if vm.nil? || tearing_down?(vm.instance_view.statuses)
35
35
  # The machine can't be found
36
36
  @logger.info('Machine not found or terminated, assuming it got destroyed.')
37
37
  machine.id = nil
@@ -40,7 +40,7 @@ module VagrantPlugins
40
40
  end
41
41
 
42
42
  # Return the state
43
- power_state(vm.properties.instance_view.statuses)
43
+ power_state(vm.instance_view.statuses)
44
44
  end
45
45
 
46
46
  end
@@ -0,0 +1,38 @@
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 'vagrant-azure/util/machine_id_helper'
8
+
9
+ module VagrantPlugins
10
+ module Azure
11
+ module Action
12
+ class ReadWinrmInfo
13
+ include VagrantPlugins::Azure::Util::MachineIdHelper
14
+
15
+ def initialize(app, env)
16
+ @app = app
17
+ @logger = Log4r::Logger.new('vagrant_azure::action::read_winrm_info')
18
+ end
19
+
20
+ def call(env)
21
+ if env[:machine].config.vm.guest == :windows
22
+ env[:machine_winrm_info] = read_winrm_info(env[:azure_arm_service], env)
23
+ end
24
+
25
+ @app.call(env)
26
+ end
27
+
28
+ def read_winrm_info(azure, env)
29
+ return nil if env[:machine].id.nil?
30
+ parsed = parse_machine_id(env[:machine].id)
31
+ public_ip = azure.network.public_ipaddresses.get(parsed[:group], "#{parsed[:name]}-vagrantPublicIP")
32
+
33
+ {:host => public_ip.dns_settings.fqdn, :port => env[:machine].config.winrm.port}
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -28,18 +28,25 @@ module VagrantPlugins
28
28
  machine = env[:machine]
29
29
 
30
30
  # Get the configs
31
- config = machine.provider_config
32
- endpoint = config.endpoint
33
- resource_group_name = config.resource_group_name
34
- location = config.location
35
- vm_name = config.vm_name
36
- vm_password = config.vm_password
37
- vm_size = config.vm_size
38
- vm_image_urn = config.vm_image_urn
39
- virtual_network_name = config.virtual_network_name
40
- subnet_name = config.subnet_name
41
- tcp_endpoints = config.tcp_endpoints
42
- availability_set_name = config.availability_set_name
31
+ config = machine.provider_config
32
+ endpoint = config.endpoint
33
+ resource_group_name = config.resource_group_name
34
+ location = config.location
35
+ ssh_user_name = machine.config.ssh.username
36
+ vm_name = config.vm_name
37
+ vm_password = config.vm_password
38
+ vm_size = config.vm_size
39
+ vm_image_urn = config.vm_image_urn
40
+ virtual_network_name = config.virtual_network_name
41
+ subnet_name = config.subnet_name
42
+ tcp_endpoints = config.tcp_endpoints
43
+ availability_set_name = config.availability_set_name
44
+ admin_user_name = config.admin_username
45
+ admin_password = config.admin_password
46
+ winrm_port = machine.config.winrm.port
47
+ winrm_install_self_signed_cert = config.winrm_install_self_signed_cert
48
+ dns_label_prefix = Haikunator.haikunate(100)
49
+ deployment_template = config.deployment_template
43
50
 
44
51
  # Launch!
45
52
  env[:ui].info(I18n.t('vagrant_azure.launching_instance'))
@@ -47,6 +54,8 @@ module VagrantPlugins
47
54
  env[:ui].info(" -- Subscription Id: #{config.subscription_id}")
48
55
  env[:ui].info(" -- Resource Group Name: #{resource_group_name}")
49
56
  env[:ui].info(" -- Location: #{location}")
57
+ env[:ui].info(" -- SSH User Name: #{ssh_user_name}") if ssh_user_name
58
+ env[:ui].info(" -- Admin Username: #{admin_user_name}") if admin_user_name
50
59
  env[:ui].info(" -- VM Name: #{vm_name}")
51
60
  env[:ui].info(" -- VM Size: #{vm_size}")
52
61
  env[:ui].info(" -- Image URN: #{vm_image_urn}")
@@ -54,6 +63,7 @@ module VagrantPlugins
54
63
  env[:ui].info(" -- Subnet Name: #{subnet_name}") if subnet_name
55
64
  env[:ui].info(" -- TCP Endpoints: #{tcp_endpoints}") if tcp_endpoints
56
65
  env[:ui].info(" -- Availability Set Name: #{availability_set_name}") if availability_set_name
66
+ env[:ui].info(" -- DNS Label Prefix: #{dns_label_prefix}")
57
67
 
58
68
  image_publisher, image_offer, image_sku, image_version = vm_image_urn.split(':')
59
69
 
@@ -65,7 +75,7 @@ module VagrantPlugins
65
75
  @logger.info("Time to fetch os image details: #{env[:metrics]['get_image_details']}")
66
76
 
67
77
  deployment_params = {
68
- dnsLabelPrefix: Haikunator.haikunate(100),
78
+ dnsLabelPrefix: dns_label_prefix,
69
79
  vmSize: vm_size,
70
80
  vmName: vm_name,
71
81
  imagePublisher: image_publisher,
@@ -73,24 +83,46 @@ module VagrantPlugins
73
83
  imageSku: image_sku,
74
84
  imageVersion: image_version,
75
85
  subnetName: subnet_name,
76
- virtualNetworkName: virtual_network_name
86
+ virtualNetworkName: virtual_network_name,
77
87
  }
78
88
 
79
- if get_image_os(image_details) != 'Windows'
89
+ # we need to pass different parameters depending upon the OS
90
+ operating_system = get_image_os(image_details)
91
+
92
+ template_params = {
93
+ operating_system: operating_system,
94
+ winrm_install_self_signed_cert: winrm_install_self_signed_cert,
95
+ winrm_port: winrm_port,
96
+ dns_label_prefix: dns_label_prefix,
97
+ location: location,
98
+ deployment_template: deployment_template
99
+ }
100
+
101
+ if operating_system != 'Windows'
80
102
  private_key_paths = machine.config.ssh.private_key_path
81
- if private_key_paths.empty?
103
+ if private_key_paths.nil? || private_key_paths.empty?
82
104
  raise I18n.t('vagrant_azure.private_key_not_specified')
83
105
  end
84
106
 
85
107
  paths_to_pub = private_key_paths.map{ |k| File.expand_path( k + '.pub') }.select{ |p| File.exists?(p) }
86
108
  raise I18n.t('vagrant_azure.public_key_path_private_key', private_key_paths.join(', ')) if paths_to_pub.empty?
109
+ deployment_params.merge!(adminUsername: ssh_user_name)
87
110
  deployment_params.merge!(sshKeyData: File.read(paths_to_pub.first))
111
+ communicator_message = 'vagrant_azure.waiting_for_ssh'
112
+ else
113
+ env[:machine].config.vm.communicator = :winrm
114
+ machine.config.winrm.port = winrm_port
115
+ machine.config.winrm.username = admin_user_name
116
+ machine.config.winrm.password = admin_password
117
+ communicator_message = 'vagrant_azure.waiting_for_winrm'
118
+ windows_params = {
119
+ adminUsername: admin_user_name,
120
+ adminPassword: admin_password,
121
+ winRmPort: winrm_port
122
+ }
123
+ deployment_params.merge!(windows_params)
88
124
  end
89
125
 
90
- template_params = {
91
- operating_system: get_image_os(image_details)
92
- }
93
-
94
126
  env[:ui].info(" -- Create or Update of Resource Group: #{resource_group_name}")
95
127
  env[:metrics]['put_resource_group'] = Util::Timer.time do
96
128
  put_resource_group(azure, resource_group_name, location)
@@ -99,11 +131,11 @@ module VagrantPlugins
99
131
 
100
132
  deployment_params = build_deployment_params(template_params, deployment_params.reject{|_,v| v.nil?})
101
133
 
102
- env[:ui].info('Starting deployment')
134
+ env[:ui].info(' -- Starting deployment')
103
135
  env[:metrics]['deployment_time'] = Util::Timer.time do
104
136
  put_deployment(azure, resource_group_name, deployment_params)
105
137
  end
106
- env[:ui].info('Finished deploying')
138
+ env[:ui].info(' -- Finished deploying')
107
139
 
108
140
  # Immediately save the ID since it is created at this point.
109
141
  env[:machine].id = serialize_machine_id(resource_group_name, vm_name, location)
@@ -111,8 +143,8 @@ module VagrantPlugins
111
143
  @logger.info("Time to deploy: #{env[:metrics]['deployment_time']}")
112
144
  unless env[:interrupted]
113
145
  env[:metrics]['instance_ssh_time'] = Util::Timer.time do
114
- # Wait for SSH to be ready.
115
- env[:ui].info(I18n.t('vagrant_azure.waiting_for_ssh'))
146
+ # Wait for SSH/WinRM to be ready.
147
+ env[:ui].info(I18n.t(communicator_message))
116
148
  network_ready_retries = 0
117
149
  network_ready_retries_max = 10
118
150
  while true
@@ -122,7 +154,7 @@ module VagrantPlugins
122
154
  rescue Exception => e
123
155
  if network_ready_retries < network_ready_retries_max
124
156
  network_ready_retries += 1
125
- @logger.warn(I18n.t('vagrant_azure.waiting_for_ssh, retrying'))
157
+ @logger.warn(I18n.t("#{communicator_message}, retrying"))
126
158
  else
127
159
  raise e
128
160
  end
@@ -131,10 +163,10 @@ module VagrantPlugins
131
163
  end
132
164
  end
133
165
 
134
- @logger.info("Time for SSH ready: #{env[:metrics]['instance_ssh_time']}")
166
+ @logger.info("Time for SSH/WinRM ready: #{env[:metrics]['instance_ssh_time']}")
135
167
 
136
168
  # Ready and booted!
137
- env[:ui].info(I18n.t('vagrant_azure.ready'))
169
+ env[:ui].info(I18n.t('vagrant_azure.ready')) unless env[:interrupted]
138
170
  end
139
171
 
140
172
  # Terminate the instance if we were interrupted
@@ -144,20 +176,21 @@ module VagrantPlugins
144
176
  end
145
177
 
146
178
  def get_image_os(image_details)
147
- image_details.properties.os_disk_image.operating_system
179
+ image_details.os_disk_image.operating_system
148
180
  end
149
181
 
150
182
  def get_image_details(azure, location, publisher, offer, sku, version)
151
183
  if version == 'latest'
152
- latest = azure.compute.virtual_machine_images.list(location, publisher, offer, sku).value!.body.last
153
- azure.compute.virtual_machine_images.get(location, publisher, offer, sku, latest.name).value!.body
184
+ images = azure.compute.virtual_machine_images.list(location, publisher, offer, sku)
185
+ latest = images.sort_by(&:name).last
186
+ azure.compute.virtual_machine_images.get(location, publisher, offer, sku, latest.name)
154
187
  else
155
- azure.compute.virtual_machine_images.get(location, publisher, offer, sku, version).value!.body
188
+ azure.compute.virtual_machine_images.get(location, publisher, offer, sku, version)
156
189
  end
157
190
  end
158
191
 
159
192
  def put_deployment(azure, rg_name, params)
160
- azure.resources.deployments.create_or_update(rg_name, 'vagrant', params).value!.body
193
+ azure.resources.deployments.create_or_update(rg_name, 'vagrant', params)
161
194
  end
162
195
 
163
196
  def put_resource_group(azure, name, location)
@@ -165,18 +198,31 @@ module VagrantPlugins
165
198
  rg.location = location
166
199
  end
167
200
 
168
- azure.resources.resource_groups.create_or_update(name, params).value!.body
201
+ azure.resources.resource_groups.create_or_update(name, params)
169
202
  end
170
203
 
171
204
  # This method generates the deployment template
172
205
  def render_deployment_template(options)
173
- Vagrant::Util::TemplateRenderer.render('arm/deployment.json', options.merge(template_root: template_root))
206
+ self_signed_cert_resource = nil
207
+ if options[:operating_system] == 'Windows' && options[:winrm_install_self_signed_cert]
208
+ setup_winrm_powershell = Vagrant::Util::TemplateRenderer.render('arm/setup-winrm.ps1', options.merge({template_root: template_root}))
209
+ encoded_setup_winrm_powershell = setup_winrm_powershell.
210
+ gsub("'", "', variables('singleQuote'), '").
211
+ gsub("\r\n", "\n").
212
+ gsub("\n", "; ")
213
+ self_signed_cert_resource = Vagrant::Util::TemplateRenderer.render('arm/selfsignedcert.json', options.merge({template_root: template_root, setup_winrm_powershell: encoded_setup_winrm_powershell}))
214
+ end
215
+ Vagrant::Util::TemplateRenderer.render('arm/deployment.json', options.merge({ template_root: template_root, self_signed_cert_resource: self_signed_cert_resource}))
174
216
  end
175
217
 
176
218
  def build_deployment_params(template_params, deployment_params)
177
219
  params = ::Azure::ARM::Resources::Models::Deployment.new
178
220
  params.properties = ::Azure::ARM::Resources::Models::DeploymentProperties.new
179
- params.properties.template = JSON.parse(render_deployment_template(template_params))
221
+ if template_params[:deployment_template].nil?
222
+ params.properties.template = JSON.parse(render_deployment_template(template_params))
223
+ else
224
+ params.properties.template = JSON.parse(template_params[:deployment_template])
225
+ end
180
226
  params.properties.mode = ::Azure::ARM::Resources::Models::DeploymentMode::Incremental
181
227
  params.properties.parameters = build_parameters(deployment_params)
182
228
  params
@@ -36,7 +36,7 @@ module VagrantPlugins
36
36
  env[:ui].info(I18n.t('vagrant_azure.waiting_for_ready'))
37
37
 
38
38
  task = await_true(env) do |vm|
39
- running?(vm.properties.instance_view.statuses)
39
+ running?(vm.instance_view.statuses)
40
40
  end
41
41
 
42
42
  if task.value
@@ -36,7 +36,7 @@ module VagrantPlugins
36
36
  env[:ui].info(I18n.t('vagrant_azure.waiting_for_stop'))
37
37
 
38
38
  task = await_true(env) do |vm|
39
- stopped?(vm.properties.instance_view.statuses)
39
+ stopped?(vm.instance_view.statuses)
40
40
  end
41
41
 
42
42
  if task.value
@@ -20,7 +20,11 @@ module VagrantPlugins
20
20
 
21
21
  begin
22
22
  env[:ui].info(I18n.t('vagrant_azure.terminating', parsed))
23
- env[:azure_arm_service].resources.resource_groups.delete(parsed[:group]).value!.body
23
+ env[:ui].info('Deleting resource group')
24
+
25
+ # Call the begin_xxx_async version to kick off the delete, but don't wait for the resource group to be cleaned up
26
+ env[:azure_arm_service].resources.resource_groups.begin_delete_async(parsed[:group]).value!
27
+ env[:ui].info('Resource group is deleting... Moving on.')
24
28
  rescue MsRestAzure::AzureOperationError => ex
25
29
  unless ex.response.status == 404
26
30
  raise ex
@@ -0,0 +1,12 @@
1
+ module VagrantPlugins
2
+ module Azure
3
+ module Cap
4
+ class WinRM
5
+ def self.winrm_info(machine)
6
+ env = machine.action('read_winrm_info')
7
+ env[:machine_winrm_info]
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -93,6 +93,26 @@ module VagrantPlugins
93
93
  # @return [String]
94
94
  attr_accessor :endpoint
95
95
 
96
+ # (Optional - requrired for Windows) The admin username for Windows templates -- ENV['AZURE_VM_ADMIN_USERNAME']
97
+ #
98
+ # @return [String]
99
+ attr_accessor :admin_username
100
+
101
+ # (Optional - Required for Windows) The admin username for Windows templates -- ENV['AZURE_VM_ADMIN_PASSWORD']
102
+ #
103
+ # @return [String]
104
+ attr_accessor :admin_password
105
+
106
+ # (Optional) Whether to automatically install a self-signed cert and open the firewall port for winrm over https -- default true
107
+ #
108
+ # @return [Bool]
109
+ attr_accessor :winrm_install_self_signed_cert
110
+
111
+ # (Optional - Required for Windows) The admin username for Windows templates -- ENV['AZURE_VM_ADMIN_PASSWORD']
112
+ #
113
+ # @return [String]
114
+ attr_accessor :deployment_template
115
+
96
116
  def initialize
97
117
  @tenant_id = UNSET_VALUE
98
118
  @client_id = UNSET_VALUE
@@ -111,6 +131,10 @@ module VagrantPlugins
111
131
  @availability_set_name = UNSET_VALUE
112
132
  @instance_ready_timeout = UNSET_VALUE
113
133
  @instance_check_interval = UNSET_VALUE
134
+ @admin_username = UNSET_VALUE
135
+ @admin_password = UNSET_VALUE
136
+ @winrm_install_self_signed_cert = UNSET_VALUE
137
+ @deployment_template = UNSET_VALUE
114
138
  end
115
139
 
116
140
  def finalize!
@@ -123,16 +147,21 @@ module VagrantPlugins
123
147
  @vm_name = Haikunator.haikunate(100) if @vm_name == UNSET_VALUE
124
148
  @resource_group_name = Haikunator.haikunate(100) if @resource_group_name == UNSET_VALUE
125
149
  @vm_password = nil if @vm_password == UNSET_VALUE
126
- @vm_image_urn = 'canonical:ubuntuserver:16.04.0-DAILY-LTS:latest' if @vm_image_urn == UNSET_VALUE
150
+ @vm_image_urn = 'canonical:ubuntuserver:16.04.0-LTS:latest' if @vm_image_urn == UNSET_VALUE
127
151
  @location = 'westus' if @location == UNSET_VALUE
128
152
  @virtual_network_name = nil if @virtual_network_name == UNSET_VALUE
129
153
  @subnet_name = nil if @subnet_name == UNSET_VALUE
130
154
  @tcp_endpoints = nil if @tcp_endpoints == UNSET_VALUE
131
- @vm_size = 'Standard_D1' if @vm_size == UNSET_VALUE
155
+ @vm_size = 'Standard_DS2_v2' if @vm_size == UNSET_VALUE
132
156
  @availability_set_name = nil if @availability_set_name == UNSET_VALUE
133
157
 
134
158
  @instance_ready_timeout = 120 if @instance_ready_timeout == UNSET_VALUE
135
159
  @instance_check_interval = 2 if @instance_check_interval == UNSET_VALUE
160
+
161
+ @admin_username = (ENV['AZURE_VM_ADMIN_USERNAME'] || 'vagrant') if @admin_username == UNSET_VALUE
162
+ @admin_password = (ENV['AZURE_VM_ADMIN_PASSWORD'] || '$Vagrant(0)') if @admin_password == UNSET_VALUE
163
+ @winrm_install_self_signed_cert = true if @winrm_install_self_signed_cert == UNSET_VALUE
164
+ @deployment_template = nil if @deployment_template == UNSET_VALUE
136
165
  end
137
166
 
138
167
  def validate(machine)
@@ -37,6 +37,11 @@ module VagrantPlugins
37
37
  Provider
38
38
  end
39
39
 
40
+ provider_capability(:azure, :winrm_info) do
41
+ require_relative 'capabilities/winrm'
42
+ VagrantPlugins::Azure::Cap::WinRM
43
+ end
44
+
40
45
  def self.setup_i18n
41
46
  I18n.load_path << File.expand_path(
42
47
  'locales/en.yml',
@@ -10,6 +10,14 @@ module VagrantPlugins
10
10
 
11
11
  def initialize(machine)
12
12
  @machine = machine
13
+
14
+ # Load the driver
15
+ machine_id_changed
16
+
17
+ # turn off nfs functionality by default, so the machine will fall back to rsync by default
18
+ @machine.config.nfs.functional = false
19
+ @machine.config.winrm.password = @machine.provider_config.admin_password
20
+ @machine.config.winrm.username = @machine.provider_config.admin_username
13
21
  end
14
22
 
15
23
  def action(name)
@@ -29,6 +37,11 @@ module VagrantPlugins
29
37
  env[:machine_ssh_info]
30
38
  end
31
39
 
40
+ def winrm_info
41
+ env = @machine.action('read_winrm_info')
42
+ env[:machine_winrm_info]
43
+ end
44
+
32
45
  def state
33
46
  # Run a custom action we define called "read_state" which does what it
34
47
  # says. It puts the state in the `:machine_state_id` key in the env
@@ -18,7 +18,7 @@ module VagrantPlugins
18
18
  end
19
19
 
20
20
  count += 1
21
- vm = azure.compute.virtual_machines.get(parsed[:group], parsed[:name], 'instanceView').value!.body
21
+ vm = azure.compute.virtual_machines.get(parsed[:group], parsed[:name], 'instanceView')
22
22
  if yield(vm)
23
23
  task.shutdown
24
24
  true
@@ -4,6 +4,6 @@
4
4
 
5
5
  module VagrantPlugins
6
6
  module Azure
7
- VERSION = '2.0.0.pre1'
7
+ VERSION = '2.0.0.pre2'.freeze
8
8
  end
9
9
  end
@@ -92,6 +92,8 @@ en:
92
92
  you can run `vagrant destroy`.
93
93
  waiting_for_ssh: |-
94
94
  Waiting for SSH to become available...
95
+ waiting_for_winrm: |-
96
+ Waiting for WinRM to become available...
95
97
  ready: |-
96
98
  Machine is booted and ready for use!
97
99
  public_key_path_private_key: |-
@@ -11,18 +11,19 @@
11
11
  },
12
12
  <% if operating_system == 'Windows' %>
13
13
  "adminPassword": {
14
- "type": "string",
14
+ "type": "securestring",
15
15
  "metadata": {
16
16
  "description": "Password for the Virtual Machine (only used on Windows)"
17
17
  }
18
18
  },
19
- <% end %>
19
+ <% else %>
20
20
  "sshKeyData": {
21
21
  "type": "string",
22
22
  "metadata": {
23
23
  "description": "SSH rsa public key file as a string."
24
24
  }
25
25
  },
26
+ <% end %>
26
27
  "dnsLabelPrefix": {
27
28
  "type": "string",
28
29
  "metadata": {
@@ -31,7 +32,7 @@
31
32
  },
32
33
  "vmSize": {
33
34
  "type": "string",
34
- "defaultValue": "Standard_D1",
35
+ "defaultValue": "Standard_DS2_v2",
35
36
  "metadata": {
36
37
  "description": "Size of the VM"
37
38
  }
@@ -58,7 +59,7 @@
58
59
  },
59
60
  "imageSku": {
60
61
  "type": "string",
61
- "defaultValue": "16.04.0-DAILY-LTS",
62
+ "defaultValue": "16.04-LTS",
62
63
  "metadata": {
63
64
  "description": "Name of the image sku"
64
65
  }
@@ -83,24 +84,33 @@
83
84
  "metadata": {
84
85
  "description": "Name of the virtual network"
85
86
  }
87
+ },
88
+ "winRmPort": {
89
+ "type": "int",
90
+ "defaultValue": 5986,
91
+ "metadata": {
92
+ "description": "WinRM port"
93
+ }
86
94
  }
87
95
  },
88
96
  "variables": {
89
97
  "storageAccountName": "[concat(uniquestring(resourceGroup().id), 'vagrant')]",
90
98
  "location": "[resourceGroup().location]",
91
- "osDiskName": "osDisk1",
99
+ "osDiskName": "[concat(parameters('vmName'), 'OSDisk1')]",
92
100
  "addressPrefix": "10.0.0.0/16",
93
101
  "subnetPrefix": "10.0.0.0/24",
94
102
  "vmStorageAccountContainerName": "vagrant-vhds",
95
103
  "nicName": "[concat(parameters('vmName'), '-vagrantNIC')]",
96
104
  "publicIPAddressName": "[concat(parameters('vmName'), '-vagrantPublicIP')]",
97
105
  "publicIPAddressType": "Dynamic",
98
- "storageAccountType": "Standard_LRS",
106
+ "storageAccountType": "Premium_LRS",
99
107
  "networkSecurityGroupName": "[concat(parameters('vmName'), '-vagrantNSG')]",
100
108
  "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]",
101
109
  "vnetID": "[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]",
102
110
  "subnetRef": "[concat(variables('vnetID'),'/subnets/',parameters('subnetName'))]",
103
- "apiVersion": "2015-06-15"
111
+ "apiVersion": "2015-06-15",
112
+ "singleQuote": "'",
113
+ "doubleQuote": "\""
104
114
  },
105
115
  "resources": [
106
116
  {
@@ -119,6 +129,36 @@
119
129
  "location": "[variables('location')]",
120
130
  "properties": {
121
131
  "securityRules": [
132
+ <% if operating_system == 'Windows' %>
133
+ {
134
+ "name": "rdp_rule",
135
+ "properties": {
136
+ "description": "Enable Inbound RDP",
137
+ "protocol": "Tcp",
138
+ "sourcePortRange": "*",
139
+ "destinationPortRange": "3389",
140
+ "sourceAddressPrefix": "*",
141
+ "destinationAddressPrefix": "*",
142
+ "access": "Allow",
143
+ "priority": 123,
144
+ "direction": "Inbound"
145
+ }
146
+ },
147
+ {
148
+ "name": "winrm_rule",
149
+ "properties": {
150
+ "description": "Enable Inbound WinRM",
151
+ "protocol": "Tcp",
152
+ "sourcePortRange": "*",
153
+ "destinationPortRange": "[parameters('winRmPort')]",
154
+ "sourceAddressPrefix": "*",
155
+ "destinationAddressPrefix": "*",
156
+ "access": "Allow",
157
+ "priority": 124,
158
+ "direction": "Inbound"
159
+ }
160
+ }
161
+ <% else %>
122
162
  {
123
163
  "name": "ssh_rule",
124
164
  "properties": {
@@ -133,6 +173,7 @@
133
173
  "direction": "Inbound"
134
174
  }
135
175
  }
176
+ <% end %>
136
177
  ]
137
178
  }
138
179
  },
@@ -210,6 +251,9 @@
210
251
  "[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]",
211
252
  "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
212
253
  ],
254
+ <% if operating_system == 'Windows' %>
255
+ <%= self_signed_cert_resource %>
256
+ <% end %>
213
257
  "properties": {
214
258
  "hardwareProfile": {
215
259
  "vmSize": "[parameters('vmSize')]"
@@ -217,6 +261,9 @@
217
261
  "osProfile": {
218
262
  "computerName": "[parameters('vmName')]",
219
263
  "adminUsername": "[parameters('adminUsername')]",
264
+ <% if operating_system == 'Windows' %>
265
+ "adminPassword": "[parameters('adminPassword')]"
266
+ <% else %>
220
267
  "linuxConfiguration": {
221
268
  "disablePasswordAuthentication": "true",
222
269
  "ssh": {
@@ -228,6 +275,7 @@
228
275
  ]
229
276
  }
230
277
  }
278
+ <% end %>
231
279
  },
232
280
  "storageProfile": {
233
281
  "imageReference": {
@@ -251,12 +299,6 @@
251
299
  "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
252
300
  }
253
301
  ]
254
- },
255
- "diagnosticsProfile": {
256
- "bootDiagnostics": {
257
- "enabled": "true",
258
- "storageUri": "[concat('http://',variables('storageAccountName'),'.blob.core.windows.net')]"
259
- }
260
302
  }
261
303
  }
262
304
  }
@@ -0,0 +1,19 @@
1
+ "resources": [
2
+ {
3
+ "type": "Microsoft.Compute/virtualMachines/extensions",
4
+ "name": "[concat(parameters('vmName'),'/WinRMCustomScriptExtension')]",
5
+ "apiVersion": "[variables('apiVersion')]",
6
+ "location": "[resourceGroup().location]",
7
+ "dependsOn": [
8
+ "[concat('Microsoft.Compute/virtualMachines/', parameters('vmName'))]"
9
+ ],
10
+ "properties": {
11
+ "publisher": "Microsoft.Compute",
12
+ "type": "CustomScriptExtension",
13
+ "typeHandlerVersion": "1.4",
14
+ "settings": {
15
+ "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -command ', variables('doubleQuote'), '& { <%= setup_winrm_powershell %> }', variables('doubleQuote'))]"
16
+ }
17
+ }
18
+ }
19
+ ],
@@ -0,0 +1,7 @@
1
+ $hostname = '<%= dns_label_prefix %>.<%= location %>.cloudapp.azure.com'
2
+ $Cert = (New-SelfSignedCertificate -CertstoreLocation Cert:/LocalMachine/My -DnsName $hostname).Thumbprint
3
+ $transport = New-Item -Path WSMan:/LocalHost/Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert -Force
4
+ cd $transport.PSPath
5
+ set-item ./HostName -value $hostname -force
6
+ set-item ./Port -value <%= winrm_port %> -force
7
+ netsh advfirewall firewall add rule name=WinRM_HTTPS dir=in action=allow protocol=TCP localport=<%= winrm_port %>
@@ -8,6 +8,7 @@ require 'vagrant-azure/version'
8
8
  Gem::Specification.new do |s|
9
9
  s.name = 'vagrant-azure'
10
10
  s.version = VagrantPlugins::Azure::VERSION
11
+ s.platform = Gem::Platform::RUBY
11
12
  s.authors = %w(Azure)
12
13
  s.description = 'Enable Vagrant to manage machines in Microsoft Azure.'
13
14
  s.summary = 'Enable Vagrant to manage Windows and Linux machines in Microsoft Azure.'
@@ -18,15 +19,16 @@ Gem::Specification.new do |s|
18
19
  s.bindir = 'bin'
19
20
  s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
21
 
21
- s.add_runtime_dependency 'azure_mgmt_resources', '~>0.2.1'
22
- s.add_runtime_dependency 'azure_mgmt_compute', '~>0.2.1'
23
- s.add_runtime_dependency 'azure_mgmt_network', '~>0.2.1'
24
- s.add_runtime_dependency 'azure_mgmt_storage', '~>0.2.1'
22
+ s.add_runtime_dependency 'azure_mgmt_resources', '~>0.8.0'
23
+ s.add_runtime_dependency 'azure_mgmt_compute', '~>0.8.0'
24
+ s.add_runtime_dependency 'azure_mgmt_network', '~>0.8.0'
25
+ s.add_runtime_dependency 'azure_mgmt_storage', '~>0.8.0'
25
26
  s.add_runtime_dependency 'haikunator', '~>1.1'
27
+ s.add_runtime_dependency 'highline', '~>1.7'
26
28
 
27
29
  s.add_development_dependency 'bundler', '~>1.9'
28
30
  s.add_development_dependency 'rake', '~>11.1'
29
31
  s.add_development_dependency 'rspec', '~>3.4'
30
- s.add_development_dependency 'simplecov', '~>0.11.2'
32
+ s.add_development_dependency 'simplecov', '~>0.11'
31
33
  s.add_development_dependency 'coveralls', '~>0.8'
32
34
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-azure
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.pre1
4
+ version: 2.0.0.pre2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Azure
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-07 00:00:00.000000000 Z
11
+ date: 2017-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: azure_mgmt_resources
@@ -16,56 +16,56 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.2.1
19
+ version: 0.8.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.2.1
26
+ version: 0.8.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: azure_mgmt_compute
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.2.1
33
+ version: 0.8.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.2.1
40
+ version: 0.8.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: azure_mgmt_network
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.2.1
47
+ version: 0.8.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 0.2.1
54
+ version: 0.8.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: azure_mgmt_storage
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.2.1
61
+ version: 0.8.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.2.1
68
+ version: 0.8.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: haikunator
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: highline
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.7'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.7'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: bundler
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -128,14 +142,14 @@ dependencies:
128
142
  requirements:
129
143
  - - "~>"
130
144
  - !ruby/object:Gem::Version
131
- version: 0.11.2
145
+ version: '0.11'
132
146
  type: :development
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
150
  - - "~>"
137
151
  - !ruby/object:Gem::Version
138
- version: 0.11.2
152
+ version: '0.11'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: coveralls
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -177,12 +191,14 @@ files:
177
191
  - lib/vagrant-azure/action/message_will_not_destroy.rb
178
192
  - lib/vagrant-azure/action/read_ssh_info.rb
179
193
  - lib/vagrant-azure/action/read_state.rb
194
+ - lib/vagrant-azure/action/read_winrm_info.rb
180
195
  - lib/vagrant-azure/action/restart_vm.rb
181
196
  - lib/vagrant-azure/action/run_instance.rb
182
197
  - lib/vagrant-azure/action/start_instance.rb
183
198
  - lib/vagrant-azure/action/stop_instance.rb
184
199
  - lib/vagrant-azure/action/terminate_instance.rb
185
200
  - lib/vagrant-azure/action/wait_for_state.rb
201
+ - lib/vagrant-azure/capabilities/winrm.rb
186
202
  - lib/vagrant-azure/config.rb
187
203
  - lib/vagrant-azure/errors.rb
188
204
  - lib/vagrant-azure/plugin.rb
@@ -198,6 +214,8 @@ files:
198
214
  - spec/vagrant-azure/config_spec.rb
199
215
  - spec/vagrant-azure/services/azure_resource_manager_spec.rb
200
216
  - templates/arm/deployment.json.erb
217
+ - templates/arm/selfsignedcert.json.erb
218
+ - templates/arm/setup-winrm.ps1.erb
201
219
  - templates/provisioners/chef-solo/solo.erb
202
220
  - vagrant-azure.gemspec
203
221
  homepage: https://github.com/azure/vagrant-azure
@@ -220,7 +238,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
220
238
  version: 1.3.1
221
239
  requirements: []
222
240
  rubyforge_project:
223
- rubygems_version: 2.4.6
241
+ rubygems_version: 2.6.9
224
242
  signing_key:
225
243
  specification_version: 4
226
244
  summary: Enable Vagrant to manage Windows and Linux machines in Microsoft Azure.