vagrant-azure 2.0.0.pre7 → 2.0.0.pre8

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.rubocop.yml +120 -0
  4. data/.travis.yml +13 -0
  5. data/Gemfile +4 -5
  6. data/README.md +98 -57
  7. data/docs/basic_linux/Vagrantfile +17 -0
  8. data/docs/basic_linux/readme.md +12 -0
  9. data/docs/basic_windows/Vagrantfile +20 -0
  10. data/docs/basic_windows/readme.md +12 -0
  11. data/docs/custom_vhd/Vagrantfile +16 -0
  12. data/docs/custom_vhd/readme.md +48 -0
  13. data/docs/data_disks/Vagrantfile +16 -0
  14. data/docs/data_disks/readme.md +20 -0
  15. data/docs/managed_image/Vagrantfile +15 -0
  16. data/docs/managed_image/readme.md +66 -0
  17. data/docs/readme.md +30 -0
  18. data/lib/vagrant-azure/action/run_instance.rb +95 -69
  19. data/lib/vagrant-azure/config.rb +75 -4
  20. data/lib/vagrant-azure/util/machine_id_helper.rb +4 -0
  21. data/lib/vagrant-azure/util/managed_image_helper.rb +26 -0
  22. data/lib/vagrant-azure/util/template_renderer.rb +54 -0
  23. data/lib/vagrant-azure/util/timer.rb +4 -0
  24. data/lib/vagrant-azure/util/vm_await.rb +4 -0
  25. data/lib/vagrant-azure/util/vm_status_translator.rb +4 -0
  26. data/lib/vagrant-azure/version.rb +1 -1
  27. data/locales/en.yml +6 -0
  28. data/spec/spec_helper.rb +1 -0
  29. data/spec/templates/arm/deployment_spec.rb +169 -0
  30. data/spec/vagrant-azure/config_spec.rb +3 -3
  31. data/templates/arm/deployment.json.erb +50 -258
  32. data/templates/arm/resources/availability_set.json.erb +6 -0
  33. data/templates/arm/resources/data_disk.json.erb +21 -0
  34. data/templates/arm/resources/import_vhd_image.json.erb +23 -0
  35. data/templates/arm/resources/linux_reset_root_ext.json.erb +20 -0
  36. data/templates/arm/resources/network_interface.json.erb +26 -0
  37. data/templates/arm/resources/network_security_group.json.erb +85 -0
  38. data/templates/arm/resources/public_ip_address.json.erb +12 -0
  39. data/templates/arm/resources/storage_account.json.erb +9 -0
  40. data/templates/arm/resources/virtual_machine.json.erb +82 -0
  41. data/templates/arm/resources/virtual_network.json.erb +27 -0
  42. data/templates/arm/resources/windows_reset_access_ext.json.erb +21 -0
  43. data/vagrant-azure.gemspec +4 -6
  44. metadata +38 -40
  45. data/spec/vagrant-azure/services/azure_resource_manager_spec.rb +0 -19
@@ -3,10 +3,12 @@
3
3
  # Licensed under the MIT License. See License in the project root for license information.
4
4
  require 'vagrant'
5
5
  require 'haikunator'
6
+ require 'vagrant-azure/util/managed_image_helper'
6
7
 
7
8
  module VagrantPlugins
8
9
  module Azure
9
10
  class Config < Vagrant.plugin('2', :config)
11
+ include VagrantPlugins::Azure::Util::ManagedImagedHelper
10
12
 
11
13
  # The Azure Active Directory Tenant ID -- ENV['AZURE_TENANT_ID']
12
14
  #
@@ -43,6 +45,16 @@ module VagrantPlugins
43
45
  # @return [String]
44
46
  attr_accessor :vm_name
45
47
 
48
+ # (Optional) DNS Name prefix of the virtual machine
49
+ #
50
+ # @return [String]
51
+ attr_accessor :dns_name
52
+
53
+ # (Optional) Network Security Group Name prefix of the virtual machine
54
+ #
55
+ # @return [String]
56
+ attr_accessor :nsg_name
57
+
46
58
  # Password for the VM -- This is not recommended for *nix deployments
47
59
  #
48
60
  # @return [String]
@@ -53,11 +65,51 @@ module VagrantPlugins
53
65
  # @return [String]
54
66
  attr_accessor :vm_size
55
67
 
56
- # (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/
68
+ # (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/
57
69
  #
58
70
  # @return [String]
59
71
  attr_accessor :vm_image_urn
60
72
 
73
+ # (Optional) Custom OS Image URI (like: http://mystorage1.blob.core.windows.net/vhds/myosdisk1.vhd) -- default nil.
74
+ #
75
+ # @return [String]
76
+ attr_accessor :vm_vhd_uri
77
+
78
+ # (Optional) The Managed Image Id which will be used to build the VM
79
+ # (like: /subscriptions/{sub_id}/resourceGroups/{group_name}/providers/Microsoft.Compute/images/{image_name}) -- default nil.
80
+ #
81
+ # @return [String]
82
+ attr_accessor :vm_managed_image_id
83
+
84
+ # (Optional unless using custom image) OS of the custom image
85
+ #
86
+ # @return [String] "Linux" or "Windows"
87
+ attr_accessor :vm_operating_system
88
+
89
+ # (Optional) Array of data disks to attach to the VM
90
+ #
91
+ # sample of creating empty data disk
92
+ # {
93
+ # name: "mydatadisk1",
94
+ # size_gb: 30
95
+ # }
96
+ #
97
+ # sample of attaching an existing VHD as a data disk
98
+ # {
99
+ # name: "mydatadisk2",
100
+ # vhd_uri: "http://mystorage.blob.core.windows.net/vhds/mydatadisk2.vhd"
101
+ # },
102
+ #
103
+ # sample of attaching a data disk from image
104
+ # {
105
+ # name: "mydatadisk3",
106
+ # vhd_uri: "http://mystorage.blob.core.windows.net/vhds/mydatadisk3.vhd",
107
+ # image: "http: //storagename.blob.core.windows.net/vhds/VMImageName-datadisk.vhd"
108
+ # }
109
+ #
110
+ # @return [Array]
111
+ attr_accessor :data_disks
112
+
61
113
  # (Optional) Name of the virtual network resource
62
114
  #
63
115
  # @return [String]
@@ -118,6 +170,7 @@ module VagrantPlugins
118
170
  # @return [String]
119
171
  attr_accessor :wait_for_destroy
120
172
 
173
+
121
174
  def initialize
122
175
  @tenant_id = UNSET_VALUE
123
176
  @client_id = UNSET_VALUE
@@ -129,8 +182,15 @@ module VagrantPlugins
129
182
  @vm_name = UNSET_VALUE
130
183
  @vm_password = UNSET_VALUE
131
184
  @vm_image_urn = UNSET_VALUE
185
+ @vm_vhd_uri = UNSET_VALUE
186
+ @vm_image_reference_id = UNSET_VALUE
187
+ @vm_operating_system = UNSET_VALUE
188
+ @vm_managed_image_id = UNSET_VALUE
189
+ @data_disks = UNSET_VALUE
132
190
  @virtual_network_name = UNSET_VALUE
133
191
  @subnet_name = UNSET_VALUE
192
+ @dsn_name = UNSET_VALUE
193
+ @nsg_name = UNSET_VALUE
134
194
  @tcp_endpoints = UNSET_VALUE
135
195
  @vm_size = UNSET_VALUE
136
196
  @availability_set_name = UNSET_VALUE
@@ -150,15 +210,24 @@ module VagrantPlugins
150
210
  @client_id = ENV['AZURE_CLIENT_ID'] if @client_id == UNSET_VALUE
151
211
  @client_secret = ENV['AZURE_CLIENT_SECRET'] if @client_secret == UNSET_VALUE
152
212
 
153
- @vm_name = Haikunator.haikunate(100) if @vm_name == UNSET_VALUE
213
+
154
214
  @resource_group_name = Haikunator.haikunate(100) if @resource_group_name == UNSET_VALUE
215
+ @vm_name = Haikunator.haikunate(100) if @vm_name == UNSET_VALUE
216
+ @vm_size = 'Standard_DS2_v2' if @vm_size == UNSET_VALUE
155
217
  @vm_password = nil if @vm_password == UNSET_VALUE
156
218
  @vm_image_urn = 'canonical:ubuntuserver:16.04.0-LTS:latest' if @vm_image_urn == UNSET_VALUE
219
+ @vm_vhd_uri = nil if @vm_vhd_uri == UNSET_VALUE
220
+ @vm_vhd_storage_account_id = nil if @vm_vhd_storage_account_id == UNSET_VALUE
221
+ @vm_operating_system = nil if @vm_operating_system == UNSET_VALUE
222
+ @vm_managed_image_id = nil if @vm_managed_image_id == UNSET_VALUE
223
+ @data_disks = [] if @data_disks == UNSET_VALUE
224
+
157
225
  @location = 'westus' if @location == UNSET_VALUE
158
226
  @virtual_network_name = nil if @virtual_network_name == UNSET_VALUE
159
227
  @subnet_name = nil if @subnet_name == UNSET_VALUE
228
+ @dns_name = nil if @dns_name == UNSET_VALUE
229
+ @nsg_name = nil if @nsg_name == UNSET_VALUE
160
230
  @tcp_endpoints = nil if @tcp_endpoints == UNSET_VALUE
161
- @vm_size = 'Standard_DS2_v2' if @vm_size == UNSET_VALUE
162
231
  @availability_set_name = nil if @availability_set_name == UNSET_VALUE
163
232
 
164
233
  @instance_ready_timeout = 120 if @instance_ready_timeout == UNSET_VALUE
@@ -167,13 +236,15 @@ module VagrantPlugins
167
236
  @admin_username = (ENV['AZURE_VM_ADMIN_USERNAME'] || 'vagrant') if @admin_username == UNSET_VALUE
168
237
  @admin_password = (ENV['AZURE_VM_ADMIN_PASSWORD'] || '$Vagrant(0)') if @admin_password == UNSET_VALUE
169
238
  @winrm_install_self_signed_cert = true if @winrm_install_self_signed_cert == UNSET_VALUE
170
- @deployment_template = nil if @deployment_template == UNSET_VALUE
171
239
  @wait_for_destroy = false if @wait_for_destroy == UNSET_VALUE
172
240
  end
173
241
 
174
242
  def validate(machine)
175
243
  errors = _detected_errors
176
244
 
245
+ errors << I18n.t("vagrant_azure.custom_image_os_error") if !@vm_vhd_uri.nil? && @vm_operating_system.nil?
246
+ errors << I18n.t("vagrant_azure.vhd_and_managed_image_error") if !@vm_vhd_uri.nil? && !@vm_managed_image_id.nil?
247
+ errors << I18n.t("vagrant_azure.manage_image_id_format_error") if !@vm_managed_image_id.nil? && !valid_image_id?(@vm_managed_image_id)
177
248
  # Azure connection properties related validation.
178
249
  errors << I18n.t('vagrant_azure.subscription_id.required') if @subscription_id.nil?
179
250
  errors << I18n.t('vagrant_azure.mgmt_endpoint.required') if @endpoint.nil?
@@ -1,3 +1,7 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+
1
5
  module VagrantPlugins
2
6
  module Azure
3
7
  module Util
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+
5
+ module VagrantPlugins
6
+ module Azure
7
+ module Util
8
+ module ManagedImagedHelper
9
+ ID_REGEX = /\/subscriptions\/(.+?)\/resourceGroups\/(.+?)\/providers\/Microsoft.Compute\/images\/(.+)/i
10
+
11
+ def image_id_matches(image_id)
12
+ image_id.match(ID_REGEX)
13
+ end
14
+
15
+ def image_id_captures(image_id)
16
+ image_id_matches(image_id).captures
17
+ end
18
+
19
+ def valid_image_id?(image_id)
20
+ match = image_id_matches(image_id)
21
+ match && match.captures.count == 3 && !match.captures.any?(&:nil?)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+
5
+ require "erb"
6
+
7
+ module VagrantPlugins
8
+ module Azure
9
+ module Util
10
+ class TemplateRenderer
11
+ class << self
12
+ # Render a given template and return the result. This method optionally
13
+ # takes a block which will be passed the renderer prior to rendering, which
14
+ # allows the caller to set any view variables within the renderer itself.
15
+ #
16
+ # @return [String] Rendered template
17
+ def render(*args)
18
+ render_with(:render, *args)
19
+ end
20
+
21
+ # Method used internally to DRY out the other renderers. This method
22
+ # creates and sets up the renderer before calling a specified method on it.
23
+ def render_with(method, template, data = {})
24
+ renderer = new(template, data)
25
+ yield renderer if block_given?
26
+ renderer.send(method.to_sym)
27
+ end
28
+ end
29
+
30
+ def initialize(template, data = {})
31
+ @data = data
32
+ @template = template
33
+ end
34
+
35
+ def render
36
+ str = File.read(full_template_path)
37
+ ERB.new(str).result(OpenStruct.new(@data).instance_eval { binding })
38
+ end
39
+
40
+ # Returns the full path to the template, taking into accoun the gem directory
41
+ # and adding the `.erb` extension to the end.
42
+ #
43
+ # @return [String]
44
+ def full_template_path
45
+ template_root.join("#{@template}.erb").to_s.squeeze("/")
46
+ end
47
+
48
+ def template_root
49
+ Azure.source_root.join("templates")
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,3 +1,7 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+
1
5
  module VagrantPlugins
2
6
  module Azure
3
7
  module Util
@@ -1,3 +1,7 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+
1
5
  module VagrantPlugins
2
6
  module Azure
3
7
  module Util
@@ -1,3 +1,7 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+
1
5
  module VagrantPlugins
2
6
  module Azure
3
7
  module Util
@@ -4,6 +4,6 @@
4
4
 
5
5
  module VagrantPlugins
6
6
  module Azure
7
- VERSION = '2.0.0.pre7'.freeze
7
+ VERSION = '2.0.0.pre8'.freeze
8
8
  end
9
9
  end
data/locales/en.yml CHANGED
@@ -114,3 +114,9 @@ en:
114
114
  Waiting for instance to become "ready"...
115
115
  waiting_for_stop: |-
116
116
  Waiting for instance to become "stopped"...
117
+ custom_image_os_error:
118
+ If you provide a custom image, you must provide the operating system for the image (vm_operating_system).
119
+ vhd_and_managed_image_error:
120
+ Specifying both vm_vhd_uri and vm_managed_image_id is not supported. Please specify one or the other.
121
+ manage_image_id_format_error:
122
+ The vm_managed_image_id doesn't fit the expected format, plese verify it looks like '/subscriptions/{sub_id}/resourceGroups/{group_name}/providers/Microsoft.Compute/images/{image_name}'
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
  # Copyright (c) Microsoft Corporation. All rights reserved.
3
3
  # Licensed under the MIT License. See License in the project root for license information.
4
+
4
5
  require 'vagrant-azure'
5
6
 
6
7
  # import all the support files
@@ -0,0 +1,169 @@
1
+ # encoding: utf-8
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License in the project root for license information.
4
+
5
+ require "spec_helper"
6
+ require "vagrant-azure/util/template_renderer"
7
+
8
+ module VagrantPlugins
9
+ module Azure
10
+ describe "deployment template" do
11
+
12
+ let(:options) {
13
+ {
14
+ operating_system: "linux",
15
+ location: "location",
16
+ endpoints: [22],
17
+ data_disks: []
18
+ }
19
+ }
20
+
21
+ describe "the basics" do
22
+ let(:subject) {
23
+ render(options)
24
+ }
25
+
26
+ it "should specify schema" do
27
+ expect(subject["$schema"]).to eq("http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json")
28
+ end
29
+
30
+ it "should specify content version" do
31
+ expect(subject["contentVersion"]).to eq("1.0.0.0")
32
+ end
33
+
34
+ it "should have 10 parameters" do
35
+ expect(subject["parameters"].count).to eq(10)
36
+ end
37
+
38
+ it "should have 14 variables" do
39
+ expect(subject["variables"].count).to eq(14)
40
+ end
41
+
42
+ it "should have 5 resources" do
43
+ expect(subject["resources"].count).to eq(5)
44
+ end
45
+ end
46
+
47
+ describe "resources" do
48
+ describe "virtual machine" do
49
+ let(:subject) {
50
+ render(options)["resources"].detect {|vm| vm["type"] == "Microsoft.Compute/virtualMachines"}
51
+ }
52
+
53
+ it "should depend on 1 resources without an AV Set" do
54
+ expect(subject["dependsOn"].count).to eq(1)
55
+ end
56
+
57
+ describe "with AV Set" do
58
+ let(:subject) {
59
+ template = render(options.merge(availability_set_name: "avSet"))
60
+ template["resources"].detect {|vm| vm["type"] == "Microsoft.Compute/virtualMachines"}
61
+ }
62
+
63
+ it "should depend on 2 resources with an AV Set" do
64
+ expect(subject["dependsOn"].count).to eq(2)
65
+ end
66
+ end
67
+
68
+ describe "with managed disk reference" do
69
+ let(:subject) {
70
+ template = render(options.merge(vm_managed_image_id: "image_id"))
71
+ template["resources"].detect {|vm| vm["type"] == "Microsoft.Compute/virtualMachines"}
72
+ }
73
+
74
+ it "should have an image reference id set to image_id" do
75
+ expect(subject["properties"]["storageProfile"]["imageReference"]["id"]).to eq("image_id")
76
+ end
77
+ end
78
+ end
79
+
80
+ describe "managed image" do
81
+ let(:subject) {
82
+ render(options)["resources"].detect {|vm| vm["type"] == "Microsoft.Compute/images"}
83
+ }
84
+ describe "with custom vhd" do
85
+ let(:vhd_uri_options) {
86
+ options.merge(
87
+ vhd_uri: "https://my_image.vhd",
88
+ operating_system: "Foo"
89
+ )
90
+ }
91
+ let(:subject) {
92
+ render(vhd_uri_options)["resources"].detect {|vm| vm["type"] == "Microsoft.Compute/images"}
93
+ }
94
+
95
+ it "should exist" do
96
+ expect(subject).not_to be_nil
97
+ end
98
+
99
+ it "should set the blob_uri" do
100
+ expect(subject["properties"]["storageProfile"]["osDisk"]["blobUri"]).to eq(vhd_uri_options[:vhd_uri])
101
+ end
102
+
103
+ it "should set the osType" do
104
+ expect(subject["properties"]["storageProfile"]["osDisk"]["osType"]).to eq(vhd_uri_options[:operating_system])
105
+ end
106
+ end
107
+
108
+ it "should not exist" do
109
+ expect(subject).to be_nil
110
+ end
111
+ end
112
+ end
113
+
114
+ describe "parameters" do
115
+ let(:base_keys) {
116
+ %w( storageAccountType adminUserName dnsLabelPrefix nsgLabelPrefix vmSize vmName subnetName virtualNetworkName
117
+ winRmPort )
118
+ }
119
+
120
+ let(:nix_keys) {
121
+ base_keys + ["sshKeyData"]
122
+ }
123
+
124
+ let(:subject) {
125
+ render(options)["parameters"]
126
+ }
127
+
128
+ it "should include all the *nix parameter keys" do
129
+ expect(subject.keys).to contain_exactly(*nix_keys)
130
+ end
131
+
132
+ describe "with Windows" do
133
+ let(:subject) {
134
+ render(options.merge(operating_system: "Windows"))["parameters"]
135
+ }
136
+
137
+ let(:win_keys) {
138
+ base_keys + ["adminPassword"]
139
+ }
140
+
141
+ it "should include all the windows parameter keys" do
142
+ expect(subject.keys).to contain_exactly(*win_keys)
143
+ end
144
+ end
145
+ end
146
+
147
+ describe "variables" do
148
+ let(:keys) {
149
+ %w(location addressPrefix subnetPrefix nicName publicIPAddressName publicIPAddressType
150
+ networkSecurityGroupName sshKeyPath vnetID subnetRef apiVersion
151
+ singleQuote doubleQuote managedImageName)
152
+ }
153
+
154
+ let(:subject) {
155
+ render(options)["variables"]
156
+ }
157
+
158
+ it "should include all the windows parameter keys" do
159
+ expect(subject.keys).to contain_exactly(*keys)
160
+ end
161
+ end
162
+
163
+
164
+ def render(options)
165
+ JSON.parse(VagrantPlugins::Azure::Util::TemplateRenderer.render("arm/deployment.json", options))
166
+ end
167
+ end
168
+ end
169
+ end